diff --git a/components/cmdline/COPYING b/components/cmdline/COPYING new file mode 100644 index 000000000..8a5c1dc3b --- /dev/null +++ b/components/cmdline/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. 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 +them 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 prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. 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. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey 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; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If 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 convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + 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. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +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. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + 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 +state 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 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 . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program 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, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU 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 Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/components/cmdline/COPYING.LESSER b/components/cmdline/COPYING.LESSER new file mode 100644 index 000000000..d74a4323d --- /dev/null +++ b/components/cmdline/COPYING.LESSER @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + 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 that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU 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 as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/components/cmdline/CmdLineExample.lpi b/components/cmdline/CmdLineExample.lpi new file mode 100644 index 000000000..24677bfa1 --- /dev/null +++ b/components/cmdline/CmdLineExample.lpi @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/cmdline/CmdLineExample.lpr b/components/cmdline/CmdLineExample.lpr new file mode 100644 index 000000000..304e97ba5 --- /dev/null +++ b/components/cmdline/CmdLineExample.lpr @@ -0,0 +1,18 @@ +program CmdLineExample; + +{$mode objfpc}{$H+} + +uses + {$IFDEF UNIX}{$IFDEF UseCThreads} + cthreads, + {$ENDIF}{$ENDIF} + Interfaces, // this includes the LCL widgetset + Forms + { add your units here }, wnmainform; + +begin + Application.Initialize; + Application.CreateForm(TWMainForm, WMainForm); + Application.Run; +end. + diff --git a/components/cmdline/cmdbox.lpk b/components/cmdline/cmdbox.lpk new file mode 100644 index 000000000..70bace22b --- /dev/null +++ b/components/cmdline/cmdbox.lpk @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/cmdline/cmdbox.pas b/components/cmdline/cmdbox.pas new file mode 100644 index 000000000..b128f2f9f --- /dev/null +++ b/components/cmdline/cmdbox.pas @@ -0,0 +1,21 @@ +{ Diese Datei wurde automatisch von Lazarus erzeugt. Sie darf nicht bearbeitet werden! +Dieser Quelltext dient nur dem Übersetzen und Installieren des Packages. + } + +unit cmdbox; + +interface + +uses + uCmdBox, LazarusPackageIntf; + +implementation + +procedure Register; +begin + RegisterUnit('uCmdBox', @uCmdBox.Register); +end; + +initialization + RegisterPackage('cmdbox', @Register); +end. diff --git a/components/cmdline/demotext.txt b/components/cmdline/demotext.txt new file mode 100644 index 000000000..a4d14cb00 --- /dev/null +++ b/components/cmdline/demotext.txt @@ -0,0 +1,59 @@ +Hello +This is a little Demo for TCmdBox +You can type commands while this text is written here ! +Available commands : + + * help : Short list for all commands + * stop : Stops me from reading this text... + * pause : Interrupts me + * resume : Continues at the last position pause was called... + * start : Restarts reading this text.. + * clear : Clears the output buffer + * clearhistory : clears history buffer for previous input + * exit : Exits the program + +A few details to TCmdBox... + +To put TCmdBox into Inputmode use (example) + +CmdBox.StartRead(clRed,clBlack,'>',clSilver,clBlack); + +If you give a string parameter to StartRead, it will be displayed directly before the input and will follow it. + +Input is received through an Event called OnInput. +Changes can be watched by the programm by OnInputChange. + +To keep TCmdBox in Inputmode just call StartRead in OnInput again. + +If you resize the application or use splitter in the middle you notice lines are wrapped, there is no fixed or limited line width. + +Input is also saved in a history list with limited to HistoryMax entries including current input. + +Output content by using: + +CmdBox.Write('Text'); + +or + +CmdBox.Writeln('Text...'); + +These calls are supposed to be Threadsafe ! + +You can use all font and background colors possible on the Operating System, for example + +CmdBox.TextColor(clRed); +CmdBox.TextBackGround(clSilver); + +or + +CmdBox.TextColors(clRed,clSilver); + +The background color of the last character in a line determines the background color of the rest of the line. + +The component should be able to show correct UTF8 codes of any kind (up to the whole 21 bits), therefore: + +€, ä, ö,ü + +should be correctly written as Euro, Ae, Oe, Ue (the last three are german) if you have selected a UTF8 capable Font and LCL-Interface. + +I hope you can use the component, if you find bugs or have suggestions contact me by email : kccmp@gmx.de \ No newline at end of file diff --git a/components/cmdline/tcmdbox.lrs b/components/cmdline/tcmdbox.lrs new file mode 100644 index 000000000..be0a225f5 --- /dev/null +++ b/components/cmdline/tcmdbox.lrs @@ -0,0 +1,19 @@ +LazarusResources.Add('TCmdBox','XPM',[ + '/* XPM */'#13#10'static char *tcmdbox[] = {'#13#10'/* width height num_color' + +'s chars_per_pixel */'#13#10'" 24 24 8 1",'#13#10'/*' + +' colors */'#13#10'"` c #C0C0C0",'#13#10'". c #000000",'#13#10'"# c #000000"' + +','#13#10'"a c #000000",'#13#10'"b c #000000",'#13#10'"c c #000000",'#13#10 + +'"d c #000000",'#13#10'"e c #000000",'#13#10'/* pixels */'#13#10'"``````````' + +'``````````````",'#13#10'"`......................`",'#13#10'"`..`...`....`..' + +'``...``.`",'#13#10'"`.`..`.`....`..`.`.`...`",'#13#10'"`.`.....`..```.``..`' + +'...`",'#13#10'"`.`..`..`..`.`.`.`.`...`",'#13#10'"`..`.....`.`.`.``...``.`"' + +','#13#10'"`......................`",'#13#10'"`......................`",'#13 + +#10'"`......................`",'#13#10'"`......................`",'#13#10'"`' + +'......................`",'#13#10'"`.````.................`",'#13#10'"`.....' + +'.................`",'#13#10'"`......................`",'#13#10'"`..........' + +'............`",'#13#10'"`......................`",'#13#10'"`...............' + +'.......`",'#13#10'"`......................`",'#13#10'"`....................' + +'..`",'#13#10'"`......................`",'#13#10'"`......................`",' + +#13#10'"`......................`",'#13#10'"````````````````````````"'#13#10 + +'};'#13#10 +]); diff --git a/components/cmdline/tcmdbox.xpm b/components/cmdline/tcmdbox.xpm new file mode 100644 index 000000000..a42b9f856 --- /dev/null +++ b/components/cmdline/tcmdbox.xpm @@ -0,0 +1,39 @@ +/* XPM */ +static char *tcmdbox[] = { +/* width height num_colors chars_per_pixel */ +" 24 24 8 1", +/* colors */ +"` c #C0C0C0", +". c #000000", +"# c #000000", +"a c #000000", +"b c #000000", +"c c #000000", +"d c #000000", +"e c #000000", +/* pixels */ +"````````````````````````", +"`......................`", +"`..`...`....`..``...``.`", +"`.`..`.`....`..`.`.`...`", +"`.`.....`..```.``..`...`", +"`.`..`..`..`.`.`.`.`...`", +"`..`.....`.`.`.``...``.`", +"`......................`", +"`......................`", +"`......................`", +"`......................`", +"`......................`", +"`.````.................`", +"`......................`", +"`......................`", +"`......................`", +"`......................`", +"`......................`", +"`......................`", +"`......................`", +"`......................`", +"`......................`", +"`......................`", +"````````````````````````" +}; diff --git a/components/cmdline/ucmdbox.pas b/components/cmdline/ucmdbox.pas new file mode 100644 index 000000000..a1ef63add --- /dev/null +++ b/components/cmdline/ucmdbox.pas @@ -0,0 +1,2385 @@ +{ Copyright (C) 2007 Julian Schutsch + + This source 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 3 of the License, or (at your option) + any later version. + + This code is distributed in the hope that 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. + + A copy of the GNU Lesser General Public License is available on the World Wide Web + at . You can also obtain it by writing + to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + Changelog: + 9.27.2007 : Seperation from another Package, first Release under GPL + Version 0.1 + 10.02.2007 : Licence Changed to LGPL + Added : History + Added : Password Input mode + Fixed : Blank Screen when Resizing so that TopLine disappears. + Added : Fixed Prompt Description infront of Input, moves along with it + Etc : Functions, minor Bugs + Missing : FreeLineWidth full support + Version 0.2 + 10.08.2007 : Removed : Fixed Line Width Support, Source now less complex + Added : Paste/Copy/Cut Ability, Select with Mouse and Shift/Keys + Added : TRTLCriticalsection called FLock to make Writeln/Write Threadsafe + Fixed : GTK 1/2 Linux support, several changes to make that work... + Removed : LineWidth, can cause Property Loading Errors if used with old Apps ! + Workarn : GTK Font height gets 2 added on all plattforms, means, win32 have two extra dots unecessarily, can't solve that ! + Fixed : Pos 1/End Key changes Scrollbar (Different GTK behaviour !) + Version 0.3 + 12.06.2008 : Optimized Color String output, still needs testing and PWD Strings are not + changed yet. Improvement visible on Win32, but still to slow, any hacks? + 17.06.2008 : TColorString changed completly, now using Arrays instead of linked lists + 25.06.2008 : Fixed everything for Multispace support + Added tabulator behaviour + Caret type and Color now customizable + Input Selection Colors published + Speed improvement using precalculated Sum-Widths for TColorString + Lots of minor UTF8 Bugs fixed + 26.06.2008 : Escape Codes for some sort of Graphical output (Tables, lines, etc) + Better moving Input + Bug fixes in MakeInputVisible + 27.06.2008 : Add FGraphicCharWidth + 28.06.2008 : New Escape Code preprocessor + Support for different modes (ANSI color, CmdBox, None(ignore)) + 29.06.2008 : FStringBuffer added,Works without WakeMainThread now as well + Fixed LineOutAndFill + Added AutoFollow + + Todo : Input Masks + Todo : Docu + +} +unit uCmdBox; + +{$mode objfpc}{$H+} + +interface + +uses Classes, SysUtils,ExtCtrls,ComCtrls,Controls,Graphics,StdCtrls,Forms,LCLType,LCLIntf, + lmessages,lresources,ClipBrd,LCLProc; + +type TCaretType=(cartLine,cartSubBar,cartBigBar,cartUser); + TEscapeCodeType=(esctCmdBox,esctAnsi,esctNone); + TEscapeMode=(escmNone,escmOperation,escmData2,escmData1,escmAnsiOperation,escmAnsiSquare); + +type TCmdBox=class; +type TColorstring=class; + +type EOnCmdBoxInput=Procedure(ACmdBox:TCmdBox;Input:String) of object; +type EOnCmdBoxInputChange=Procedure(ACmdBox:TCmdBox;InputData:TColorstring) of object; + +type + +{ TCmdBox } + +TCmdBox=class(TCustomControl) + public + constructor Create(AComponent:TComponent);override; + destructor Destroy;override; + protected + procedure Paint;override; + procedure Resize;override; + procedure UTF8KeyPress(var Key:TUTF8Char);override; + procedure KeyDown(var Key:Word;Shift:TShiftState);override; + procedure CreateParams(var Params:TCreateParams);override; + procedure CreateWnd;override; + procedure WMVScroll(var message: TLMVScroll);message LM_VSCROLL; + private + FLock : System.TRTLCriticalSection; + FCaretTimer : TTimer; + FCaretVisible : Boolean; + FLineCount : Integer; + FLines : array of TColorstring; + FLineHeights : array of Integer; + FLineHeightSum : array of Integer; + FTopLine : Integer; + FPageHeight : Integer; + FVisibleLines : Integer; + FVSBVisible : Boolean; + FVSBPos : Integer; + FVSBWidth : Integer; + FClientWidth : Integer; + FClientHeight : Integer; + FCaretX : Integer; + FOutX,FOutY : Integer; + FInputX,FInputY : Integer; + FInputPos : Integer; + FCharHeight : Integer; + FLineOfTopLine : Integer; + FVisibleLineCount : Integer; + FInput : Boolean; + FInputBuffer : TColorstring; + FInputVisible : Boolean; + FInputMinPos : Integer; + FUTF8InputMinPos : Integer; + FOnInput : EOnCmdBoxInput; + FOnAny : EOnCmdBoxInputChange; + FOnInputChange : EOnCmdBoxInputChange; + FBackGroundColor : TColor; + FCurrentColor : TColor; + FCurrentBackGround : TColor; + FFont : TFont; + FPassWordChar : TUTF8Char; + FInputIsPassWord : Boolean; + FHistory : Array of TColorstring; + FHistoryLength : Integer; + FHistoryMax : Integer; + FHistoryPos : Integer; + FInputColor : TColor; + FInputBackground : TColor; + FInputSelColor : TColor; + FInputSelBackGround : TColor; + FMouseDown : Boolean; + FSelStart,FSelEnd : Integer; + FMouseDownInputPos : Integer; + FCurrentString : String; + FCaretColor : TColor; + FCaretType : TCaretType; + FCaretWidth : Integer; + FCaretHeight : Integer; + FCaretYShift : Integer; + FTabWidth : Integer; + FGraphicCharWidth : Integer; + FEscapeCodeType : TEscapeCodeType; + FEscapeMode : TEscapeMode; + FEscapeData : String; + FStringBuffer : TStringList; + FAutoFollow : Boolean; + procedure CaretTimerExecute(Sender:TObject); + procedure SetLineCount(c:Integer); + procedure SetTopLine(Nr:Integer); + procedure AdjustScrollBars; + function AdjustLineHeight(i:Integer):Integer; + procedure MakeInputVisible; + procedure MakeOutVisible; + procedure SetFont(F:TFont); + procedure SetBackGroundColor(c:Tcolor); + function GetSystemMetricsGapSize(const Index:Integer):Integer; + procedure ScrollBarRange(Which: Integer; aRange,aPage: Integer); + procedure ScrollBarPosition(Which,Value:Integer); + function UpdateLineHeights:Integer; + procedure TranslateScrollBarPosition; + procedure ScrollUp; + procedure SetHistoryMax(v:Integer); + procedure InsertHistory; + procedure SetHistoryPos(v:Integer); + procedure EraseBackground(DC:HDC);override; + function GetHistory(i:Integer):string; + procedure DeleteHistoryEntry(i:Integer); + procedure MakeFirstHistoryEntry(i:Integer); + procedure MouseDown(Button:TMouseButton;Shift:TShiftState;x,y:Integer);override; + procedure MouseUp(Button:TMouseButton;Shift:TShiftState;x,y:Integer);override; + procedure MouseMove(Shift:TShiftState;x,y:Integer);override; + function MoveInputCaretTo(x,y:Integer;chl:Boolean):Boolean; + procedure SetSelection(Start,Ende:Integer); + procedure LeftSelection(Start,Ende:Integer); + procedure RightSelection(Start,Ende:Integer); + procedure DeleteSelected; + procedure SetOutY(v:Integer); + procedure IntWrite; + procedure MultiWrite; + procedure SetCaretType(ACaretType:TCaretType); + procedure SetCaretWidth(AValue:Integer); + procedure SetCaretHeight(AValue:Integer); + procedure SetCaretYShift(AValue:Integer); + procedure SetTabWidth(AValue:Integer); + function GetCaretInterval:Integer; + procedure SetCaretInterval(AValue:Integer); + + public + + function HistoryHas(s:string):Boolean; + function HistoryIndexOf(s:string):Integer; + procedure ClearHistory; + procedure TextColor(C:TColor); + procedure TextBackground(C:TColor); + procedure TextColors(FC,BC:TColor); + procedure Write(s:String); + procedure Writeln(s:String); + procedure WriteStream(Stream:TStream); + procedure Clear; + procedure StartRead(DFC,DBC:TColor;const Desc:String;IFC,IBC:TColor); + procedure StartReadPassWord(DFC,DBC:TColor;const Desc:String;IFC,IBC:TColor); + procedure StopRead; + procedure CopyToClipBoard; + procedure PasteFromClipBoard; + procedure CutToClipBoard; + procedure ClearLine; + property OutX : Integer read FOutX write FOutX; + property OutY : Integer read FOutY write SetOutY; + property TopLine : Integer read FTopLine write SetTopLine; + property History[i:Integer] : string read GetHistory; + property InputPos : Integer read FInputPos; + function HistoryCount : Integer; + published + property Align; + property Anchors; + property ShowHint; + property CaretColor : TColor read FCaretColor write FCaretColor; + property CaretType : TCaretType read FCaretType write SetCaretType; + property CaretWidth : Integer read FCaretWidth write SetCaretWidth; + property CaretHeight : Integer read FCaretHeight write SetCaretHeight; + property CaretYShift : Integer read FCaretYShift write SetCaretYShift; + property OnInput : EOnCmdBoxInput read FOnInput write FOnInput; + property OnInputChange : EOnCmdBoxInputChange read FOnInputChange write FOnInputChange; + property OnAny : EOnCmdBoxInputChange read FOnAny write FOnAny; + property LineCount : Integer read FLineCount write SetLineCount; + property Font : TFont read FFont write SetFont; + property BackGroundColor : TColor read FBackgroundColor write SetBackGroundColor; + property TabWidth : Integer read FTabWidth write SetTabWidth; + property PassWordChar : TUTF8Char read FPassWordChar write FPassWordChar; + property HistoryMax : Integer read FHistoryMax write SetHistoryMax; + property InputSelColor : TColor read FInputSelColor write FInputSelColor; + property InputSelBackGround : TColor read FInputSelBackGround write FInputSelBackGround; + property CaretInterval : Integer read GetCaretInterval write SetCaretInterval; + property EscapeCodeType : TEscapeCodeType read FEscapeCodeType write FEscapeCodeType; + property GraphicalCharacterWidth : Integer read FGraphicCharWidth write FGraphicCharWidth; + property AutoFollow : Boolean read FAutoFollow write FAutoFollow; + property DoubleBuffered default true; + end; + +type TColorChar=record + FChar : TUTF8Char; + FCharWidth : Integer; + FSumWidth : Integer; + FWordStart : Integer; + FFrontColor : TColor; + FBackColor : TColor; + end; + +type TColorString=class + private + FChars : array of TColorChar; + FSumWidth : Integer; + FPassWordStart : Integer; + FPassWordChar : TUTF8Char; + FTabWidth : Integer; + procedure MinimumLength(V:Integer;FC,BC:TColor); + procedure MaximumLength(V:Integer); + procedure UpdateSum; + public + constructor Create(AFont:TFont); + destructor Destroy;override; + procedure Clear; + procedure OverWrite(S:String;Pos:Integer;FC,BC:TColor); + procedure OverWriteChar(s:TUTF8Char;Pos,ADefWidth:Integer;FC,BC:TColor); + procedure OverWrite(S:TColorstring;Pos:Integer); + procedure OverWritePW(S:TColorstring;PWS,Pos:Integer;PWC:String); + procedure PartOverWrite(S:TColorstring;Start,Ende,Pos:Integer); + procedure LineOutAndFill(ACanvas:TCanvas;AX,AY,ALeftX,AWrapWidth,ACH,ACB,ACaretPos:Integer;ABC,ACC:TColor;ACaretHeight,ACaretWidth,ACaretYShift:Integer;ADrawCaret:Boolean); + function Getstring:String; + function GetPartstring(Start,Ende:Integer):String; + procedure Delete(Index:Integer); + procedure Delete(Index,Len:Integer); + procedure Insert(Index:Integer;C:String;FC,BC:TColor); + procedure BColorBlock(StartPos,EndPos:Integer;C:TColor); + procedure ColorBlock(StartPos,EndPos:Integer;FC,BC:TColor); + function LineCount(AWrapWidth,ACaretPos,ACaretWidth:Integer):Integer; + function GetLength:Integer; + function GetLineOfCaret(AWrapWidth,ACaretPos,ACaretWidth:Integer):Integer; + function GetCharPosition(AWrapWidth,ALine,AXPos:Integer):Integer; + private + FFont : TFont; + FDefaultBackGround : TColor; + public + property TabWidth : Integer read FTabWidth write FTabWidth; + property PassWordChar : TUTF8Char read FPassWordChar write FPassWordChar; + property PassWordStart : Integer read FPassWordStart write FPassWordStart; + property Length : Integer read GetLength; + property DefaultBackGround : TColor read FDefaultBackground write FDefaultBackground; + property Font : TFont read FFont write FFont; + end; + +procedure Register; + +implementation + +procedure TColorString.UpdateSum; +var i : Integer; + LastWordStart : Integer; + SumWidth : Integer; +begin + LastWordStart := 0; + SumWidth := 0; + for i:=0 to High(FChars) do + begin + with FChars[i] do + begin + FWordStart := LastWordStart; + case FChar[1] of + #9: + begin + FCharWidth := (SumWidth div FTabWidth+1)*FTabWidth-SumWidth; + LastWordStart := i+1; + end; + #27: + begin + case FChar[2] of + #9: + begin + FCharWidth := (SumWidth div FTabWidth+1)*FTabWidth-SumWidth; + LastWordStart := i+1; + end; + #10:LastWordStart:=i+1; + #32,#46,#196,#205: + begin + FCharWidth := Ord(FChar[3]); + LastWordStart := i+1; + end; + #33,#47,#197,#206: + begin + FCharWidth := (Ord(FChar[3])+Ord(FChar[4])*256)-SumWidth; + if FCharWidth<0 then FCharWidth:=0; + LastWordStart := i+1; + end; + end; + end; + else if FChar=' ' then LastWordStart:=i+1; + end; + SumWidth := SumWidth+FCharWidth; + FSumWidth := SumWidth; + end; + end; + FSumWidth:=SumWidth; +end; + +function TColorString.GetLength:Integer; +begin + Result:=System.Length(FChars); +end; + +procedure TCmdBox.SetTabWidth(AValue:Integer); +var i:Integer; +begin + FTabWidth:=AValue; + for i:=0 to FLineCount-1 do FLines[i].TabWidth:=AValue; + UpdateLineHeights; + Invalidate; +end; + +procedure TCmdBox.SetCaretWidth(AValue:Integer); +begin + FCaretWidth := AValue; + FCaretType := cartUser; +end; + +procedure TCmdBox.SetCaretHeight(AValue:Integer); +begin + FCaretHeight := AValue; + FCaretType := cartUser; +end; + +procedure TCmdBox.SetCaretYShift(AValue:Integer); +begin + FCaretYShift := AValue; + FCaretType := cartUser; +end; + +procedure TCmdBox.SetCaretType(ACaretType:TCaretType); +begin + case ACaretType of + cartLine: + begin + if HandleAllocated then FCaretHeight:=FFont.GetTextHeight('A')-3 else FCaretHeight:=-1; + FCaretWidth := 1; + FCaretYShift := 3; + end; + cartSubBar: + begin + FCaretWidth := -1; + FCaretHeight := 3; + FCaretYShift := 0; + end; + cartBigBar: + begin + if HandleAllocated then FCaretHeight:=FFont.GetTextHeight('A')-3 else FCaretHeight:=-1; + FCaretWidth := -1; + FCaretYShift := 3; + end; + end; + Invalidate; + FCaretType:=ACaretType; +end; + +// TOdo : Use string buffer instead of string (speed improvement expected) +procedure TColorString.LineOutAndFill(ACanvas:TCanvas;AX,AY,ALeftX,AWrapWidth,ACH,ACB,ACaretPos:Integer;ABC,ACC:TColor;ACaretHeight,ACaretWidth,ACaretYShift:Integer;ADrawCaret:Boolean); +var LineStart : Integer; + LineEnd : Integer; + MidWidth : Integer; + LineStartSumWidth : Integer; + x : Integer; + LastLineSumWidth : Integer; + ACHH : Integer; + ACBH : Integer; + +procedure DrawLine; +var SameColor : String; + SameForeColor : TColor; + SameBackColor : TColor; + SameColorX : Integer; + SameColorWidth : Integer; + LP : Integer; + CaretX : Integer; + CaretW : Integer; + CW : Integer; + xp : Integer; +begin + if (AY<=-ACH) and (AY>ACanvas.Height) then + begin + Inc(AY,ACH); + Ax:=ALeftx; + Exit; + end; + SameColor:=''; + ACanvas.Brush.Style:=bsSolid; + // TODO: Please try to reproduce this Ultra-Shit Error which couples GetTextWidth input to + // TextOut Output. I can't solve this...i am not Stupid Enough for such errors! + // (Is in bug report, should be fixed somewhere in the future!) + ACanvas.Font.GetTextWidth('%%%_$%_Hallo\\\\\\\\\32489738'); + // End of shit + LP := LineStart; + CaretX := -1; + while LineStart<>LineEnd+1 do + begin + with FChars[LineStart] do + begin + CW:=FCharWidth; + if FChar=#9 then + begin + if SameColor<>'' then + begin + ACanvas.Font.Color :=SameForeColor; + ACanvas.Brush.Color :=SameBackColor; + ACanvas.FillRect(SameColorX,AY,SameColorX+SameColorWidth,Ay+ACH); + ACanvas.TextOut(SameColorX,AY,SameColor); + Inc(SameColorX,SameColorWidth); + SameColor:=''; + end else SameColorX:=AX; + ACanvas.Brush.Color:=FBackColor; + ACanvas.Fillrect(SameColorX,AY,SameColorX+FCharWidth,AY+ACH); + end + else + if FChar[1]=#27 then + begin + if SameColor<>'' then + begin + ACanvas.Font.Color :=SameForeColor; + ACanvas.Brush.Color :=SameBackColor; + ACanvas.FillRect(SameColorX,AY,SameColorX+SameColorWidth,Ay+ACH); + ACanvas.TextOut(SameColorX,AY,SameColor); + Inc(SameColorX,SameColorWidth); + SameColor:=''; + end else SameColorX:=AX; + case FChar[2] of + #9: + begin + case FChar[3] of + #46: + begin + ACanvas.Pen.Color:=FFrontColor; + ACanvas.Pen.Style:=psDash; + ACanvas.Brush.Color:=FBackColor; + ACanvas.Fillrect(SameColorX,AY,SameColorX+FCharWidth,AY+ACH); + xp:=SameColorX; + if xp mod 2<>0 then Inc(xp); + while xp0 then Inc(xp); + while xp=FPassWordStart) then + begin + SameColor := FPassWordChar; + SameColorWidth := FFont.GetTextWidth(FPassWordChar); + end + else + begin + SameColor := FChar; + SameColorWidth := FCharWidth; + end; + SameColorX := AX; + SameForeColor := FFrontColor; + SameBackColor := FBackColor; + end + else + begin + if (SameForeColor=FFrontColor) and (SameBackColor=FBackColor) then + begin + if (LP>=FPassWordStart) then + begin + SameColor:=SameColor+FPassWordChar; + Inc(SameColorWidth,FFont.GetTextWidth(FPassWordChar)); + end + else + begin + SameColor:=SameColor+FChar; + Inc(SameColorWidth,FCharWidth); + end; + end + else + begin + ACanvas.Font.Color :=SameForeColor; + ACanvas.Brush.Color :=SameBackColor; + ACanvas.FillRect(SameColorX,Ay,SameColorX+SameColorWidth,Ay+ACH); + ACanvas.TextOut(SameColorX,AY,SameColor); + if (LP>=FPassWordStart) then + begin + SameColor := FPassWordChar; + SameColorWidth := FFont.GetTextWidth(FPassWordChar); + end + else + begin + SameColor := FChar; + SameColorWidth := FCharWidth; + end; + SameForeColor := FFrontColor; + SameBackColor := FBackColor; + SameColorX := AX; + end; + end; + if LP=ACaretPos then + begin + CaretX:=AX; + CaretW:=FCharWidth; + end; + Inc(AX,CW); + Inc(LP); + end; + Inc(LineStart); + end; + if SameColor<>'' then + begin + ACanvas.Font.Color := SameForeColor; + ACanvas.Brush.Color := SameBackColor; + ACanvas.FillRect(SameColorX,Ay,SameColorX+SameColorWidth,Ay+ACH); + ACanvas.TextOut(SameColorX,AY,SameColor); + end; + ACanvas.FillRect(AX,AY,AWrapWidth,AY+ACH); + AX:=ALeftX; + Inc(AY,ACH); + if ADrawCaret and (CaretX>=0) then + begin + ACanvas.Brush.Color:=ACC; + if ACaretWidth>=0 then CaretW:=ACaretWidth; + ACanvas.FillRect(CaretX,AY-ACaretHeight-ACaretYShift,CaretX+CaretW,AY-ACaretYShift); + end; +end; + +begin + if AWrapWidth<0 then AWrapWidth:=0; + if System.Length(FChars)=0 then + begin + ACanvas.Brush.Style := bsSolid; + ACanvas.Brush.Color := ABC; + ACanvas.FillRect(AX,AY,AWrapWidth,AY+ACH); + Exit; + end; + ACHH := ACH div 2; + ACBH := ACB div 2; + MidWidth := FSumWidth div System.Length(FChars); + LineStart := 0; + LineStartSumWidth := 0; + LastLineSumWidth := 0; + x := 0; + while LineStartHigh(FChars) then x:=High(FChars); + while (xLineStart) and (FChars[x].FSumWidth-LineStartSumWidth>=AWrapWidth) do + with FChars[x] do if (FChar<>' ') and (FWordStart>LineStart) then x:=FWordStart-1 else Dec(x); + LineEnd:=x; + DrawLine; + LastLineSumWidth := LineStartSumWidth; + LineStartSumWidth := FChars[x].FSumWidth; + LineStart := x+1; + end; + if ACaretPos>=LineStart then + begin + if ACaretWidth>=0 then x:=ACaretWidth else x:=FFont.GetTextWidth('A'); + AX:=LineStartSumWidth-LastLineSumWidth+(ACaretPos-LineStart)*x; + if Ax+x>AWrapWidth then + begin + Ax:=0; + ACanvas.Brush.Color:=ABC; + ACanvas.FillRect(0,AY,AWrapWidth,AY+ACH); + Inc(Ay,ACH); + end; + if ADrawCaret then + begin + ACanvas.Brush.Color:=ACC; + ACanvas.FillRect(AX,AY-ACaretHeight-ACaretYShift,AX+x,AY-ACaretYShift); + end; + end; +end; + +function TColorString.GetCharPosition(AWrapWidth,ALine,AXPos:Integer):Integer; +var x,MidWidth,LineStart,LineStartSumWidth,LastLineSumWidth,LastLineStart:Integer; +begin + if AWrapWidth<0 then AWrapWidth:=0; + if System.Length(FChars)=0 then + begin + Result:=0; + Exit; + end; + MidWidth := FSumWidth div System.Length(FChars); + if MidWidth=0 then + begin + Result:=0; + Exit; + end; + LineStart := 0; + LineStartSumWidth := 0; + LastLineSumWidth := 0; + x:=0; + while (LineStart=0) do + begin + x:=LineStart+AWrapWidth div MidWidth; + if x>High(FChars) then x:=High(FChars); + while (xLineStart) and (FChars[x].FSumWidth-LineStartSumWidth>=AWrapWidth) do + with FChars[x] do if (FChar<>' ') and (FWordStart>LineStart) then x:=FWordStart-1 else Dec(x); + LastLineSumWidth := LineStartSumWidth; + LineStartSumWidth := FChars[x].FSumWidth; + LastLineStart := LineStart; + LineStart := x+1; + Dec(ALine); + end; + Result:=LastLineStart; + while (ResultHigh(FChars) then x:=High(FChars); + while (xLineStart) and (FChars[x].FSumWidth-LineStartSumWidth>=AWrapWidth) do + with FChars[x] do if (FChar<>' ') and (FWordStart>LineStart) then x:=FWordStart-1 else Dec(x); + LastLineSumWidth := LineStartSumWidth; + LineStartSumWidth := FChars[x].FSumWidth; + LineStart := x+1; + if ACaretPos=0 then x:=ACaretWidth else x:=FFont.GetTextWidth('A'); + if (ACaretPos>LineStart) or (LineStartSumWidth-LastLineSumWidth+(ACaretPos-LineStart)*x+x<=AWrapWidth) then Dec(Result); +end; + +function TColorString.LineCount(AWrapWidth,ACaretPos,ACaretWidth:Integer):Integer; +var x : Integer; + MidWidth : Integer; + LineStart : Integer; + LineStartSumWidth : Integer; + LastLineSumWidth : Integer; +begin + if AWrapWidth<0 then AWrapWidth:=0; + if System.Length(FChars)=0 then + begin + Result:=1; + Exit; + end; + MidWidth := FSumWidth div System.Length(FChars); + if MidWidth=0 then + begin + Result:=1; + Exit; + end; + LineStart := 0; + LineStartSumWidth := 0; + LastLineSumWidth := 0; + Result:=0; + x:=0; + while LineStartHigh(FChars) then x:=High(FChars); + while (xLineStart) and (FChars[x].FSumWidth-LineStartSumWidth>=AWrapWidth) do + with FChars[x] do if (FChar<>' ') and (FWordStart>LineStart) then x:=FWordStart-1 else Dec(x); + LastLineSumWidth := LineStartSumWidth; + LineStartSumWidth := FChars[x].FSumWidth; + LineStart := x+1; + Inc(Result); + end; + if ACaretWidth>=0 then x:=ACaretWidth else x:=FFont.GetTextWidth('A'); + if (ACaretPos>=LineStart) and (LineStartSumWidth-LastLineSumWidth+(ACaretPos-LineStart)*x+x>AWrapWidth) then Inc(Result); +end; + +constructor TColorString.Create(AFont:TFont); +begin + inherited Create; + FTabWidth := 1; + FFont := AFont; + FPassWordStart := MaxInt; +end; + +procedure TColorstring.BColorBlock(StartPos,EndPos:Integer;C:TColor); +var i:Integer; +begin + if StartPos<0 then StartPos:=0; + if EndPos>High(FChars) then EndPos:=High(FChars); + for i:=StartPos to EndPos do FChars[i].FBackColor:=C; +end; + +procedure TColorstring.ColorBlock(StartPos,EndPos:Integer;FC,BC:TColor); +var i:Integer; +begin + if StartPos<0 then StartPos:=0; + if EndPos>High(FChars) then EndPos:=High(FChars); + for i:=StartPos to EndPos do + begin + FChars[i].FFrontColor := FC; + FChars[i].FBackColor := BC; + end; +end; + +procedure TColorstring.Insert(Index:Integer;C:string;FC,BC:TColor); +var i : Integer; + l : Integer; + Pp : Integer; + OldLen : Integer; + SLen : Integer; +begin + OldLen := System.Length(FChars); + SLen := UTF8Length(C); + if OldLen=FPassWordStart then FCharWidth:=FFont.GetTextWidth(FPassWordChar) else FCharWidth:=FFont.GetTextWidth(FChar); + FFrontColor := FC; + FBackColor := BC; + end; + Inc(pp,l); + end; + UpdateSum; +end; + +procedure TColorstring.Delete(Index,Len:Integer); +var i:Integer; +begin + if (Len=0) or (Index>=System.Length(FChars)) then Exit; + if Index+Len>System.Length(FChars) then Len:=System.Length(FChars)-Index; + for i:=Index to System.Length(FChars)-Len-1 do FChars[i]:=FChars[i+Len]; + SetLength(FChars,System.Length(FChars)-Len); + UpdateSum; +end; + +procedure TColorstring.Delete(Index:Integer); +var i:Integer; +begin + if (Index>=System.Length(FChars)) then Exit; + for i:=Index to System.Length(FChars)-2 do FChars[i]:=FChars[i+1]; + SetLength(FChars,System.Length(FChars)-1); + UpdateSum; +end; + +function TColorstring.GetPartstring(Start,Ende:Integer):string; +var i,n : Integer; + Len : Integer; +begin + if Start<0 then Start:=0; + if Ende>High(FChars) then Ende:=High(FChars); + Len:=0; + for i:=Start to Ende do Inc(Len,System.Length(FChars[i].FChar)); + SetLength(Result,Len); + Len:=1; + for i:=Start to Ende do + begin + with FChars[i] do + begin + for n:=1 to System.Length(FChar) do + begin + Result[Len]:=FChar[n]; + Inc(Len); + end; + end; + end; +end; + +function TColorstring.Getstring:String; +var i,n : Integer; + Len : Integer; +begin + Len := 0; + for i:=0 to High(FChars) do Inc(Len,System.Length(FChars[i].FChar)); + SetLength(Result,Len); + Len := 1; + for i:=0 to High(FChars) do + begin + with FChars[i] do + begin + for n:=1 to System.Length(FChar) do + begin + Result[Len]:=FChar[n]; + Inc(Len); + end; + end; + end; +end; + +procedure TColorstring.OverWritePW(S:TColorstring;PWS,Pos:Integer;PWC:String); +var i : Integer; + CPassWordStart:Integer; +begin + MinimumLength(Pos+S.Length,CLSilver,S.FDefaultBackGround); + CPassWordStart:=PWS; + for i:=0 to S.Length-1 do + begin + FChars[i+Pos]:=S.FChars[i]; + if CPassWordStart<=0 then FChars[i+Pos].FChar:=PWC; + Dec(CPassWordStart); + end; + UpdateSum; +end; + +procedure TColorstring.OverWrite(S:TColorstring;Pos:Integer); +var i : Integer; +begin + MinimumLength(Pos+S.Length,CLSilver,S.FDefaultBackGround); + for i:=0 to S.Length-1 do FChars[i+Pos]:=S.FChars[i]; + UpdateSum; +end; + +procedure TColorstring.PartOverWrite(S:TColorstring;Start,Ende,Pos:Integer); +var i : Integer; +begin + MinimumLength(Pos+Ende-Start,CLSilver,S.FDefaultBackGround); + for i:=0 to Ende-Start-1 do FChars[i+Pos]:=S.FChars[i+Start]; + UpdateSum; +end; + +procedure TColorstring.OverWrite(s:String;Pos:Integer;FC,BC:TColor); +var i,Pp,l : Integer; +begin + MinimumLength(Pos+UTF8Length(S),FC,BC); + Pp:=1; + for i:=0 to UTF8Length(S)-1 do + begin + l:=UTF8CharacterLength(@s[Pp]); + with FChars[i+Pos] do + begin + FChar := Copy(S,Pp,l); + FCharWidth := FFont.GetTextWidth(FChar); + FFrontColor := FC; + FBackColor := BC; + end; + Inc(Pp,l); + end; + UpdateSum; +end; + +procedure TColorstring.OverWriteChar(s:TUTF8Char;Pos,ADefWidth:Integer;FC,BC:TColor); +begin + MinimumLength(Pos+1,FC,BC); + with FChars[Pos] do + begin + FChar := s; + FCharWidth := ADefWidth; + FFrontColor := FC; + FBackColor := BC; + end; + UpdateSum; +end; + +procedure TColorstring.MinimumLength(V:Integer;FC,BC:TColor); +var OldLen,i:Integer; +begin + if System.Length(FChars)V then SetLength(FChars,V); +end; + +procedure TColorstring.Clear; +begin + FChars:=Nil; +end; + +procedure TCmdBox.ClearLine; +begin + if FLines[FOutY].Length<>0 then + begin + FLines[FOutY].Clear; + FOutX:=0; + if FInput then FInputY:=FOutY; + Invalidate; + end; +end; + +function TCmdBox.GetCaretInterval:Integer; +begin + Result:=FCaretTimer.Interval; +end; + +procedure TCmdBox.SetCaretInterval(AValue:Integer); +begin + FCaretTimer.Interval:=AValue; +end; + +procedure TCmdBox.MultiWrite; +var DoWrite:Boolean; +begin + System.EnterCriticalSection(FLock); + DoWrite:=FStringBuffer.Count<>0; + if DoWrite then + begin + FCurrentString:=FStringBuffer[0]; + FStringBuffer.Delete(0); + end; + System.LeaveCriticalSection(FLock); + if DoWrite then IntWrite; +end; + +procedure TCmdBox.Write(S:String); +begin + if ThreadID=MainThreadId then + begin + MultiWrite; + FCurrentString:=S; + IntWrite; + end + else + begin + System.EnterCriticalSection(FLock); + FStringBuffer.Add(S); + System.LeaveCriticalSection(FLock); + if Assigned(WakeMainThread) then TThread.Synchronize(Nil,@MultiWrite); + end; +end; + +function TCmdBox.HistoryIndexOf(s:string):Integer; +begin + for Result:=0 to HistoryCount-1 do if History[Result]=s then Exit; + Result:=-1; +end; + +function TCmdBox.HistoryHas(s:string):Boolean; +var i:Integer; +begin + Result := True; + for i:=0 to HistoryCount-1 do if History[i]=s then Exit; + Result := False; +end; + +function TCmdBox.HistoryCount:Integer; +begin + HistoryCount:=FHistoryLength-Ord(FInput); +end; + +function TCmdBox.GetHistory(i:Integer):string; +begin + Inc(i,Ord(FInput)); + if (i>=0) and (iFHistoryMax then + begin + if FHistoryLength>v then FHistoryLength:=v; + for i:=v to FHistoryMax-1 do FHistory[i].Free; + SetLength(FHistory,v); + for i:=FHistoryMax to v-1 do FHistory[i]:=TColorstring.Create(Canvas.Font); + FHistoryMax:=v; + end; +end; + +procedure TCmdBox.WriteStream(Stream:TStream); +var c:wideString; +begin + while Stream.Position-1 then FInputBuffer.ColorBlock(FSelStart,FSelEnd,FInputColor,FInputBackGround); + if Start=Ende then FSelStart:=-1 else + begin + if Start-1 then FInputBuffer.ColorBlock(FSelStart,FSelEnd,FInputSelColor,FInputSelBackGround); +end; + +procedure TCmdBox.CopyToClipBoard; +begin + if FSelStart<>-1 then + begin + ClipBoard.AsText:=FInputBuffer.GetPartstring(FSelStart,FSelEnd); + end; +end; + +procedure TCmdBox.PasteFromClipBoard; +var s:widestring; + l,Pp:Integer; +begin + if ClipBoard.HasFormat(CF_TEXT) then + begin + s := ClipBoard.AsText; + Pp := 1; + while pp<=Length(s) do + begin + l := UTF8CharacterLength(@S[Pp]); + if (l=1) and (Byte(S[Pp])<32) then Delete(s,Pp,1) else inc(Pp,l); + end; + FInputBuffer.Insert(InputPos,s,FInputColor,FInputBackGround); + Inc(InputPos,UTF8Length(s)); + FCaretX:=FInputX+InputPos; + AdjustScrollBars; + MakeInputVisible; + FHistoryPos:=0; + if Assigned(FOnInputChange) then FOnInputChange(Self,FInputBuffer); + if Assigned(FOnAny) then FOnAny(Self,FInputBuffer); + end; +end; + +procedure TCmdBox.DeleteSelected; +begin + if FSelStart<>-1 then + begin + FInputBuffer.Delete(FSelStart,FSelEnd-FSelStart+1); + FInputPos := FSelStart; + FCaretX := FInputX+FInputPos; + FSelStart := -1; + end; +end; + +procedure TCmdBox.CutToClipBoard; +begin + if FSelStart<>-1 then + begin + ClipBoard.AsText:=FInputBuffer.GetPartstring(FSelStart,FSelEnd); + DeleteSelected; + end; +end; + +procedure TCmdBox.MouseMove(Shift:TShiftState;x,y:Integer); +begin + if FMouseDown then + begin + if MoveInputCaretTo(x,y,false) then SetSelection(FMouseDownInputPos,FInputPos); + end; +end; + +function TCmdBox.MoveInputCaretTo(x,y:Integer;chl:Boolean):Boolean; +var h,sl,q:Integer; +begin + if not FInput then Exit; + y := y div FCharHeight; + h := FLineHeightSum[FTopLine]+FLineOfTopLine+y; + sl := FTopLine; + while (slFInputBuffer.Length) then q:=FInputBuffer.Length-FInputX; + FCaretX := q; + FInputPos := FCaretX-FInputX; + if Assigned(FOnAny) then FOnAny(Self,FInputBuffer); + Invalidate; + Result:=True; + end else Result:=False; +end; + +procedure TCmdBox.MouseDown(Button:TMouseButton;Shift:TShiftState;x,y:Integer); +begin + SetFocus; + MoveInputCaretTo(x,y,True); + FMouseDown:=True; + SetSelection(-1,0); + FMouseDownInputPos:=FInputPos; + Invalidate; +end; + +procedure TCmdBox.MouseUp(Button:TMouseButton;Shift:TShiftState;x,y:Integer); +begin + FMouseDown:=False; +end; + +destructor TColorstring.Destroy; +begin + Clear; + inherited Destroy; +end; + +procedure TCmdBox.ScrollUp; +var n:Integer; + Firstwidestring : TColorstring; +begin + Firstwidestring:=FLines[0]; + for n:=0 to Length(FLines)-2 do Flines[n] := FLines[n+1]; + Firstwidestring.Clear; + Firstwidestring.FDefaultBackGround := FBackGroundColor; + Flines[High(Flines)]:=Firstwidestring; +end; + +procedure TCmdBox.TextColors(FC,BC:TColor); +begin + FCurrentColor := FC; + FCurrentBackGround := BC; +end; + +procedure TCmdBox.TextColor(C:TColor); +begin + FCurrentColor:=C; +end; + +procedure TCmdBox.TextBackGround(C:TColor); +begin + FCurrentBackGround:=C; +end; + +procedure TCmdBox.TranslateScrollBarPosition; +var GLine,Line : Integer; + He :Integer; +begin + if (FLineOfTopLineFVisibleLineCount-FPageHeight then CurrentPos:=FVisibleLineCount-FPageHeight; + {$IFNDEF LCLGTK} + ScrollBarPosition(SB_VERT, CurrentPos); + {$ENDIF} + + FVSBPos:=CurrentPos; + TranslateScrollBarPosition; +end; + +procedure TCmdBox.ScrollBarRange(Which: Integer; aRange,aPage: Integer); +var ScrollInfo: TScrollInfo; +begin + if HandleAllocated then + begin + FillChar(ScrollInfo, SizeOf(ScrollInfo), 0); + ScrollInfo.cbSize := SizeOf(ScrollInfo); + ScrollInfo.fMask := SIF_RANGE or SIF_PAGE or SIF_DISABLENOSCROLL; + // Dont't know, someone told me to kick it...so i did:P +// {$ifdef Unix} +{ ScrollInfo.fMask := ScrollInfo.fMask or SIF_UPDATEPOLICY; + if goThumbTracking in Options then + ScrollInfo.ntrackPos := SB_POLICY_CONTINUOUS + else + ScrollInfo.ntrackPos := SB_POLICY_DISCONTINUOUS;} +// {$endif}} + ScrollInfo.nMin := 0; + ScrollInfo.nMax := ARange; + if APage<0 then APage := 0; + ScrollInfo.nPage := APage; + SetScrollInfo(Handle, Which, ScrollInfo, True); + end; +end; + +procedure TCmdBox.ScrollBarPosition(Which, Value: integer); +var ScrollInfo : TScrollInfo; + Vis : Boolean; +begin + if HandleAllocated then + begin + if Which = SB_VERT then Vis := FVSbVisible else + FillChar(ScrollInfo, SizeOf(ScrollInfo), 0); + ScrollInfo.cbSize := SizeOf(ScrollInfo); + ScrollInfo.fMask := SIF_POS; + ScrollInfo.nPos := Value; + SetScrollInfo(Handle, Which, ScrollInfo, Vis); + end; +end; + +function TCmdBox.GetSystemMetricsGapSize(const Index:Integer):Integer; +begin + {$ifdef LCLWIN32} + result:=0; + {$else} + result:=3; + {$endif} +end; + +procedure TCmdBox.SetBackGroundColor(c:TColor); +begin + if c<>FBackGroundColor then + begin + FBackGroundColor:=c; + Invalidate; + end; +end; + +procedure TCmdBox.SetFont(F:TFont); +var DC : HDC; + Save : THandle; + Metrics : TTextMetric; +begin + FFont.Assign(F); + Canvas.Font := FFont; + DC := GetDC(0); + Save := SelectObject(DC,FFont.Handle); + GetTextMetrics(DC, Metrics); + SelectObject(DC, Save); + ReleaseDC(0, DC); + FCharHeight := Abs(Metrics.tmHeight)+2; + Invalidate; +end; + +// Still a Bug: Try having a cmdline with more lines than fit on screen : update doesn't work anymore... + +procedure TCmdBox.MakeInputVisible; +var y : Integer; +begin + if not FAutoFollow then Exit; + UpdateLineHeights; + y:=FLineHeightSum[FInputY]+FInputBuffer.GetLineOfCaret(FClientWidth,FCaretX,FCaretWidth); + if y>=FLineHeightSum[FTopLine]+FLineOfTopLine+FPageHeight then + begin + While y>=FLineHeightSum[FTopLine]+FLineHeights[FTopLine]+FPageHeight-1 do Inc(FTopLine); + FLineOfTopLine:=y-(FLineHeightSum[FTopLine]+FPageHeight)+1; + end + else if yFVSBPos then + begin + FVSBPos:=y; + if HandleAllocated then ScrollBarPosition(SB_Vert,y); + end; +end; + +procedure TCmdBox.MakeOutVisible; +var y : Integer; +begin + if not FAutoFollow then Exit; + UpdateLineHeights; + y:=FLineHeightSum[FOutY]+FLines[FOutY].GetLineOfCaret(FClientWidth,FOutX,FCaretWidth); + if y>=FLineHeightSum[FTopLine]+FLineOfTopLine+FPageHeight then + begin + While y>=FLineHeightSum[FTopLine]+FLineHeights[FTopLine]+FPageHeight-1 do Inc(FTopLine); + FLineOfTopLine:=y-(FLineHeightSum[FTopLine]+FPageHeight)+1; + end + else if yFVSBPos then + begin + FVSBPos:=y; + if HandleAllocated then ScrollBarPosition(SB_Vert,y); + end; +end; + +procedure TCmdBox.SetHistoryPos(v:Integer); +begin + if FInputIsPassWord then Exit; + if v<0 then v:=FHistoryLength-1 else if v>=FHistoryLength then v:=0; + if v<>FHistoryPos then + begin + if FHistoryPos=0 then + begin + FHistory[0].Clear; + FHistory[0].PartOverWrite(FInputBuffer,FInputMinPos,FInputBuffer.Length,0); + end; + FInputBuffer.MaximumLength(FInputMinPos+FHistory[v].Length); + FInputBuffer.OverWrite(FHistory[v],FInputMinPos); + if FInputPos>FInputBuffer.Length then + begin + FInputPos:=FInputBuffer.Length; + FCaretX:=FInputX+FInputPos; + end; + FHistoryPos:=v; + end; + if Assigned(FOnInputChange) then FOnInputChange(Self,FInputBuffer); + MakeInputVisible; + AdjustLineHeight(FInputY); + AdjustScrollBars; + Invalidate; +end; + +procedure TCmdBox.UTF8KeyPress(var Key:TUTF8Char); +begin + if not FInput then Exit; + if key>=#32 then + begin + if FSelStart<>-1 then DeleteSelected; + FInputBuffer.Insert(FInputPos,key,FInputColor,FInputBackGround); + Inc(FInputPos); + FCaretX:=FInputX+FInputPos; + FHistoryPos:=0; + if assigned(FOnInputChange) then FOnInputChange(Self,FInputBuffer); + end; + if Assigned(OnAny) then OnAny(Self,FInputBuffer); + AdjustScrollBars; + MakeInputVisible; + If FInputVisible then Invalidate; +end; + +procedure TCmdBox.KeyDown(var Key:Word;Shift:TShiftState); +var s : String; + i : Integer; +begin + if not FInput then Exit; + case Key of + VK_END: + begin + key:=0; + if (not (ssAlt in Shift)) and FInput and (FInputPos<>FInputBuffer.Length) then + begin + if not (ssShift in Shift) then SetSelection(-1,0) else RightSelection(FInputPos,FInputBuffer.Length); + FInputPos:=FInputBuffer.Length; + FCaretX:=FInputX+FInputPos; + MakeInputVisible; + Invalidate; + end; + end; + VK_HOME: + begin + key:=0; + if (not (ssAlt in Shift)) and FInput and (FInputPos<>FInputMinPos) then + begin + if not (ssShift in Shift) then SetSelection(-1,0) else LeftSelection(FInputMinPos,FInputPos); + FInputPos:=FInputMinPos; + FCaretX:=FInputX+FInputPos; + MakeInputVisible; + Invalidate; + end; + end; + VK_LEFT: + begin + if (not (ssAlt in Shift)) and (FInput and (FInputPos>FInputMinPos)) then + begin + if not (ssShift in Shift) then SetSelection(-1,0) else LeftSelection(FInputPos-1,FInputPos); + Dec(FInputPos); + FCaretX:=FInputX+FInputPos; + MakeInputVisible; + Invalidate; + end; + end; + VK_UP: + begin + if (not (ssAlt in Shift)) and FInput then + begin + SetSelection(-1,0); + SetHistoryPos(FHistoryPos+1); + end; + end; + VK_DOWN: + begin + if (not (ssAlt in Shift)) and FInput then + begin + SetSelection(-1,0); + SetHistoryPos(FHistoryPos-1); + end; + end; + VK_RIGHT: + begin + if (not (ssAlt in Shift)) and FInput and (FInputPos-1 then DeleteSelected else FInputBuffer.Delete(FInputPos); + FHistoryPos:=0; + if assigned(FOnInputChange) then FOnInputChange(Self,FInputBuffer); + MakeInputVisible; + AdjustLineHeight(FInputY); + AdjustScrollBars; + end; + end; + VK_RETURN: + begin + if FInput then + begin + s := FInputBuffer.GetString; + s := Copy(s,FUTF8InputMinPos+1,Length(s)); + if (FHistoryPos=0) then + begin + if (FInputBuffer.Length=FInputMinPos) or FInputIsPassWord then + begin + DeleteHistoryEntry(0); + end + else + begin + i:=HistoryIndexOf(s); + if i>=0 then + begin + DeleteHistoryEntry(0); + MakeFirstHistoryEntry(i); + end + else + begin + FHistory[0].Clear; + FHistory[0].PartOverWrite(FInputBuffer,FInputMinPos,FInputBuffer.Length,0); + end; + end; + end + else + begin + DeleteHistoryEntry(0); + MakeFirstHistoryEntry(FHistoryPos); + end; + FInput := False; + if FLines[FOutY].Length<>0 then + begin + if FOutY>=FLineCount-1 then + begin + ScrollUp; + Dec(FOutY); + FInputY:=FOutY; + AdjustLineHeight(FOutY); + UpdateLineHeights; + TranslateScrollBarPosition; + end; + FLines[FOutY+1].Clear; + FLines[FOutY+1].OverWrite(FLines[FOutY],0); + FLines[FOutY].Clear; + if FInputIsPassWord then + FLines[FOutY].OverWritePW(FInputBuffer,FInputMinPos,FInputX,FPassWordChar) + else FLines[FOutY].OverWrite(FInputBuffer,FInputX); + end + else + begin + if FInputIsPassWord then + FLines[FOutY].OverWritePW(FInputBuffer,FInputMinPos,FInputX,FPassWordChar) + else FLines[FOutY].OverWrite(FInputBuffer,FInputX); + end; + Inc(FOutY); + if FOutY>=FLineCount then + begin + ScrollUp; + Dec(FOutY); + FInputY:=FOutY; + AdjustLineHeight(FOutY); + UpdateLineHeights; + TranslateScrollBarPosition; + end; + FOutX := 0; + FCaretX := 0; + FInputBuffer.Clear; + if Assigned(OnInput) then OnInput(Self,s); + if Assigned(OnAny) then OnAny(Self,FInputBuffer); + AdjustScrollBars; + Invalidate; + end; + end; + VK_BACK: + begin + if FInput then + begin + if FSelStart<>-1 then DeleteSelected else + begin + If (FInputPos>FInputMinPos) then + begin + Dec(FInputPos); + FInputBuffer.Delete(FInputPos); + FCaretX:=FInputX+FInputPos; + end; + end; + FHistoryPos:=0; + if assigned(FOnInputChange) then FOnInputChange(Self,FInputBuffer); + if Assigned(OnAny) then OnAny(Self,FInputBuffer); + AdjustScrollBars; + MakeInputVisible; + If FInputVisible then Invalidate; + end; + end; + VK_C: + begin + if (FInput) and (ssCtrl in Shift) then CopyToClipBoard; + end; + VK_V: + begin + if (FInput) and (ssCtrl in Shift) then PasteFromClipBoard; + end; + VK_X: + begin + if (FInput) and (ssCtrl in Shift) then CutToClipBoard; + end; + VK_A: + begin + if (FInput) and (ssCtrl in Shift) then + begin + SetSelection(FInputMinPos,FInputBuffer.Length); + FInputPos:=FInputBuffer.Length; + MakeInputVisible; + if FInputVisible then Invalidate; + end; + end; + end; + if Assigned(OnAny) then OnAny(Self,FInputBuffer); +end; + +procedure TCmdBox.InsertHistory; +var i : Integer; + t : TColorstring; +begin + t:=FHistory[FHistoryMax-1]; + for i:=FHistoryMax-2 downto 0 do + begin + FHistory[i+1]:=FHistory[i]; + end; + FHistory[0] := t; + FHistoryPos := 0; + If FHistoryLengthLength(Desc) then Break; + case Desc[Pp+1] of + #9,#10,#32,#46,#196: + begin + if Pp+2>Length(Desc) then Break; //Incomplete Escape Seq...ignore + l:=3; + end; + #33,#47,#197: + begin + if Pp+3>Length(Desc) then Break; //Incomplete Escape Seq...ignore + l:=4; + end; + else + begin + l:=2; + end; + end; + end else l:=UTF8CharacterLength(@Desc[PP]); + FInputBuffer.OverWriteChar(Copy(Desc,Pp,l),i,FGraphicCharWidth,DFC,DBC); + Inc(i); + Inc(Pp,l); + end; + FInputPos := i; + FInputMinPos := i; +// FInputBuffer.OverWrite(Desc,0,DFC,DBC); + FInputIsPassWord := False; + FInputColor := IFC; + FInputBackground := IBC; + FInputBuffer.PassWordStart:=MaxInt; + InsertHistory; + MakeInputVisible; +end; + +procedure TCmdBox.StartReadPassWord(DFC,DBC:TColor;const Desc:string;IFC,IBC:TColor); +begin + StartRead(DFC,DBC,Desc,IFC,IBC); + FInputBuffer.PassWordStart := UTF8Length(Desc); + FInputBuffer.PassWordChar := FPassWordChar; + FInputIsPassWord := True; +end; + +procedure TCmdBox.StopRead; +begin + FInput:=False; +end; + +procedure TCmdBox.DeleteHistoryEntry(i:Integer); +var j:Integer; + Temp:TColorstring; +begin + Temp:=FHistory[i]; + for j:=i to FHistoryLength-2 do FHistory[j]:=FHistory[j+1]; + FHistory[FHistoryLength-1]:=Temp; + Dec(FHistoryLength); + if FHistoryPos>=i then Dec(FHistoryPos); +end; + +procedure TCmdBox.MakeFirstHistoryEntry(i:Integer); +var Temp:TColorstring; +begin + if FHistoryPos<>0 then + begin + Temp:=FHistory[i]; + for i:=i-1 downto 0 do FHistory[i+1]:=FHistory[i]; + FHistory[0]:=Temp; + end; +end; + +procedure TCmdBox.Clear; +var i:Integer; +begin + for i:=0 to Length(FLines)-1 do Flines[i].Clear; + FCaretX := 0; + FInputY := 0; + FOutX := 0; + FOutY := 0; + if FInput then FInputY:=0; + Invalidate; +end; + +procedure TCmdBox.Writeln(s:string); +begin + write(s+#13#10); +end; + +const AnsiColors:array['0'..'7'] of TColor=(clBlack,clRed,clGreen,clYellow,clBlue,clFuchsia,clAqua,clWhite); + +procedure TCmdBox.IntWrite; +var Pp : Integer; + SLen : Integer; + l : Integer; + s : String; + EscString : String; + EscPos : Integer; + EscSubMode : Integer; +begin + S := FCurrentString; + SLen := UTF8Length(S); + Pp := 1; + while Pp<=Length(S) do + begin + l:=1; + case FEscapeMode of + escmNone: + begin + if S[Pp]=#27 then + begin + case FEscapeCodeType of + esctCmdBox: + begin + FEscapeMode := escmOperation; + FEscapeData := ''; + end; + esctAnsi: + begin + FEscapeMode := escmAnsiOperation; + FEscapeData := ''; + end; + esctNone: + begin + // Simply ignore it + end; + end; + end + else + begin + l:=UTF8CharacterLength(@S[Pp]); + if l=1 then + begin + case s[Pp] of + #13:FOutX:=0; + #10: + begin + AdjustLineHeight(FOutY); + if FLines[FOutY].Length=0 then FLines[FOutY].DefaultBackGround:=FCurrentBackGround; + Inc(FOutY); + if FOutY>=Length(FLines) then + begin + ScrollUp; + Dec(FOutY); + AdjustLineHeight(FOutY); + UpdateLineHeights; + TranslateScrollBarPosition; + end; + end; + else + begin + FLines[FOutY].OverWrite(s[Pp],FOutX,FCurrentColor,FCurrentBackGround); + Inc(FOutX); + end; + end; + end + else + begin + FLines[FOutY].OverWrite(Copy(s,Pp,l),FOutX,FCurrentColor,FCurrentBackGround); + Inc(FOutX); + end; + end; + end; + escmOperation: + begin + case S[Pp] of + #9,#10,#32,#46,#196: + begin + FEscapeData := S[Pp]; + FEscapeMode := escmData1; + end; + #33,#47,#197: + begin + FEscapeData := S[Pp]; + FEscapeMode := escmData2; + end; + else + begin + FLines[FOutY].OverWriteChar(#27+S[Pp],FOutX,FGraphicCharWidth,FCurrentColor,FCurrentBackGround); + Inc(FOutX); + FEscapeMode:=escmNone; + end; + end; + end; + escmData1: + begin + FLines[FOutY].OverWriteChar(#27+FEscapeData+S[Pp],FOutX,FGraphicCharWidth,FCurrentColor,FCurrentBackGround); + Inc(FOutX); + FEscapeMode:=escmNone; + end; + escmData2: + begin + FEscapeData := FEscapeData+S[Pp]; + FEscapeMode := escmData1; + end; + escmAnsiOperation: + begin + case S[Pp] of + '[':FEscapeMode:=escmAnsiSquare; + else FEscapeMode:=escmNone; + end; + end; + escmAnsiSquare: + begin + case S[Pp] of + 'm': + begin + EscPos := 1; + EscSubMode := 0; + while EscPos<=Length(FEscapeData) do + begin + case EscSubMode of + 0: + begin + case FEscapeData[EscPos] of + '0': + begin + // No Reset Values know here...just assume + FCurrentColor:=clSilver; + FCurrentBackGround:=clBlack; + end; + '7': + begin + // Reverse? What now... + end; + '3':EscSubMode:=3; + '4':EscSubMode:=4; + end; + end; + 1: + begin + // Just collect the expected ";", not sure what to do if it isn't there... + EscSubMode:=0; + end; + 3: + begin + if FEscapeData[EscPos] in ['0'..'7'] then FCurrentColor:=AnsiColors[FEscapeData[EscPos]]; + EscSubMode:=1; + end; + 4: + begin + if FEscapeData[EscPos] in ['0'..'7'] then FCurrentBackGround:=AnsiColors[FEscapeData[EscPos]]; + EscSubMode:=1; + end; + end; + Inc(EscPos); + end; + FEscapeMode:=escmNone; + end; + else + begin + FEscapeData:=FEscapeData+S[Pp]; + end; + end; + end; + end; + Inc(Pp,l); + end; + if FInput then + begin + if FLines[FOutY].Length=0 then + begin + if (FInputY<>FOutY) then FInputY:=FOutY; + end + else + begin + if FInputY<>FOutY+1 then FInputY:=FOutY+1; + end; + if FInputY>=FLineCount then + begin + ScrollUp; + Dec(FOutY); + Dec(FInputY); + FInputY:=FOutY; + AdjustLineHeight(FOutY); + UpdateLineHeights; + TranslateScrollBarPosition; + end; + MakeInputVisible; + end else MakeOutVisible; + AdjustLineHeight(FOutY); + if not FInput then FCaretX:=FOutX; + AdjustScrollBars; +end; + +procedure TCmdBox.SetOutY(v:Integer); +begin + if v>FLineCount-1 then v:=FLineCount-1; + FOutY:=v; +end; + +procedure TCmdBox.Resize; +begin + inherited Resize; + AdjustScrollBars; + if FVSBPos>=FVisibleLineCount-FPageHeight then + begin + FVSBPos:=FVisibleLineCount-FPageHeight; + if FVSBPos<0 then FVSBPos:=0; + end; + TranslateScrollBarPosition; +end; + +function TCmdBox.AdjustLineHeight(i:Integer):Integer; +var LineC : Integer; + LineC2 : Integer; +begin + if (FInputY=i) then + begin + LineC := FLines[i].LineCount(FClientWidth,-1,FCaretWidth); + LineC2 := FInputBuffer.LineCount(FClientWidth,FCaretX,FCaretWidth); + if LineC2>LineC then LineC:=LineC2; + end else LineC:=FLines[i].LineCount(FClientWidth,-1,FCaretWidth); + Result := LineC; + FLineHeights[i] := Result; +end; + +function TCmdBox.UpdateLineHeights:integer; +var i:integer; +begin + Result:=0; + for i:=0 to FLineCount-1 do + begin + FLineHeightSum[i]:=Result; + Inc(Result,AdjustLineHeight(i)); + end; +end; + +procedure TCmdBox.AdjustScrollBars; +var LH : Integer; +begin + FClientWidth := Width-FVSBWidth; + FClientHeight := Height; + FPageHeight := FClientHeight div FCharHeight; + FVisibleLines := FPageHeight+ord(FClientHeight mod FCharHeight<>0); + LH := UpdateLineHeights; + if LH<>FVisibleLineCount then + begin + FVisibleLineCount:=LH; + if FVisibleLineCount<=FVSBPos+FPageHeight then + begin + FVSBPos:=FVisibleLineCount-FPageHeight; + if FVSBPos<0 then FVSBPos:=0; + if HandleAllocated then ScrollBarPosition(SB_Vert,FVSBPos); + TranslateScrollBarPosition; + end; + end; + if FVisibleLineCountFTopLine then + begin + FTopLine:=Nr; + AdjustScrollBars; + end; +end; + +procedure TCmdBox.SetLineCount(c: Integer); +var i:Integer; +begin + if c<1 then c:=1; + if c<>FLineCount then + begin + for i:=0 to FLineCount-1 do FLines[i].Free; + FLineCount:=c; + SetLength(FLines,FLinecount); + for i:=0 to FlineCount-1 do + begin + FLines[i]:=TColorstring.Create(Canvas.Font); + FLines[i].DefaultBackGround:=FBackGroundColor; + FLines[i].TabWidth:=FTabWidth; + end; + SetLength(FLineHeights,FLineCount); + SetLength(FLineHeightSum,FLineCount); + AdjustScrollBars; + end; +end; + +procedure TCmdBox.Paint; +Var y,m : Integer; + CurrentLine : Integer; +begin + inherited Paint; + with canvas do + begin + if (csdesigning in componentstate) then + begin + Brush.Style := bsSolid; + Brush.Color := clBlack; + FillRect(0,0,FClientWidth,FClientHeight); + exit; + end; + Font := FFont; + Brush.Style := bsSolid; + m := FVisibleLines-1; + y := -FLineOfTopLine; + CurrentLine := FTopLine; + while (y<=m) and (CurrentLine'#2#6'Height'#3#224#1 + +#5'Width'#2#5#5'Align'#7#7'alRight'#7'Beveled'#9#12'ResizeAnchor'#7#7'akRigh' + +'t'#0#0#7'TCmdBox'#6'CmdBox'#6'Height'#3#224#1#5'Width'#3'>'#2#5'Align'#7#8 + +'alClient'#10'CaretColor'#4#255#128#0#0#9'CaretType'#7#8'cartUser'#10'CaretW' + +'idth'#2#1#11'CaretHeight'#2#13#11'CaretYShift'#2#3#7'OnInput'#7#11'CmdBoxIn' + +'put'#9'LineCount'#3#232#3#12'Font.CharSet'#7#12'ANSI_CHARSET'#10'Font.Color' + +#7#8'clSilver'#11'Font.Height'#2#240#9'Font.Name'#6#5'Arial'#10'Font.Pitch'#7 + +#10'fpVariable'#15'BackGroundColor'#7#6'clNavy'#8'TabWidth'#2'<'#12'PassWord' + +'Char'#6#1'*'#10'HistoryMax'#2#10#13'InputSelColor'#7#8'clPurple'#18'InputSe' + +'lBackGround'#7#8'clSilver'#13'CaretInterval'#3#244#1#23'GraphicalCharacterW' + +'idth'#2#10#10'AutoFollow'#9#0#0#6'TTimer'#11'ReaderTimer'#8'Interval'#3#188 + +#2#7'OnTimer'#7#16'ReaderTimerTimer'#4'left'#2'B'#3'top'#2'K'#0#0#6'TTimer' + +#12'ProcessTimer'#7'Enabled'#8#8'Interval'#2'd'#7'OnTimer'#7#17'ProcessTimer' + +'Timer'#4'left'#2'h'#3'top'#2'K'#0#0#0#10'TWMainForm'#9'WMainForm'#4'Left'#3 + +'?'#1#6'Height'#3#224#1#3'Top'#3'Q'#1#5'Width'#3#208#2#13'ActiveControl'#7#6 + +'CmdBox'#7'Caption'#6#27'TCmdBox Example Application'#12'ClientHeight'#3#224 + +#1#11'ClientWidth'#3#208#2#8'OnCreate'#7#10'FormCreate'#9'OnDestroy'#7#11'Fo' + +'rmDestroy'#8'Position'#7#14'poScreenCenter'#10'LCLVersion'#6#6'0.9.25'#0#6 + +'TPanel'#10'RightPanel'#4'Left'#3'C'#2#6'Height'#3#224#1#5'Width'#3#141#0#5 + +'Align'#7#7'alRight'#12'ClientHeight'#3#224#1#11'ClientWidth'#3#141#0#8'TabO' + +'rder'#2#0#0#6'TLabel'#6'Label1'#4'Left'#2#16#6'Height'#2#14#3'Top'#2#8#5'Wi' + +'dth'#2'#'#7'Caption'#6#7'History'#11'ParentColor'#8#0#0#7'TButton'#7'Button' + +'1'#4'Left'#2#16#6'Height'#2#25#3'Top'#3#184#1#5'Width'#2'm'#7'Anchors'#11#6 + +'akLeft'#7'akRight'#8'akBottom'#0#25'BorderSpacing.InnerBorder'#2#4#7'Captio' + +'n'#6#12'End Programm'#7'OnClick'#7#12'Button1Click'#8'TabOrder'#2#0#0#0#8'T' + +'ListBox'#11'HistoryList'#4'Left'#2#16#6'Height'#3#29#1#3'Top'#2#24#5'Width' + +#2'm'#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#8'akBottom'#0#8'TabOrder'#2 + +#1#0#0#7'TButton'#7'Button2'#4'Left'#2#16#6'Height'#2#25#3'Top'#3';'#1#5'Wid' + +'th'#2'm'#7'Anchors'#11#6'akLeft'#7'akRight'#8'akBottom'#0#25'BorderSpacing.' + +'InnerBorder'#2#4#7'Caption'#6#5'Clear'#7'OnClick'#7#12'Button2Click'#8'TabO' + +'rder'#2#2#0#0#9'TComboBox'#10'CbSetCaret'#4'Left'#2#16#6'Height'#2#21#3'Top' + +#3#141#1#5'Width'#2'm'#7'Anchors'#11#6'akLeft'#7'akRight'#8'akBottom'#0#16'A' + +'utoCompleteText'#11#22'cbactEndOfLineComplete'#20'cbactSearchAscending'#0#10 + +'ItemHeight'#2#13#9'ItemIndex'#2#0#13'Items.Strings'#1#6#10'Caret-Line'#6#13 + +'Caret-Sub-Bar'#6#13'Caret-Big-Bar'#0#8'OnChange'#7#16'CbSetCaretChange'#5'S' + +'tyle'#7#14'csDropDownList'#8'TabOrder'#2#3#4'Text'#6#10'Caret-Line'#0#0#7'T' + +'Button'#7'Button3'#4'Left'#2#16#6'Height'#2#25#3'Top'#3'a'#1#5'Width'#2'm'#7 + +'Anchors'#11#6'akLeft'#7'akRight'#8'akBottom'#0#7'Caption'#6#7'Process'#7'On' + +'Click'#7#12'Button3Click'#8'TabOrder'#2#4#0#0#0#9'TSplitter'#9'Splitter1'#4 + ,'Left'#3'>'#2#6'Height'#3#224#1#5'Width'#2#5#5'Align'#7#7'alRight'#7'Beveled' + +#9#12'ResizeAnchor'#7#7'akRight'#0#0#7'TCmdBox'#6'CmdBox'#6'Height'#3#224#1#5 + +'Width'#3'>'#2#5'Align'#7#8'alClient'#10'CaretColor'#4#255#128#0#0#9'CaretTy' + +'pe'#7#8'cartUser'#10'CaretWidth'#2#1#11'CaretHeight'#2#13#11'CaretYShift'#2 + +#3#7'OnInput'#7#11'CmdBoxInput'#9'LineCount'#3#232#3#12'Font.CharSet'#7#12'A' + +'NSI_CHARSET'#10'Font.Color'#7#8'clSilver'#11'Font.Height'#2#240#9'Font.Name' + +#6#5'Arial'#10'Font.Pitch'#7#10'fpVariable'#15'BackGroundColor'#7#6'clNavy'#8 + +'TabWidth'#2'<'#12'PassWordChar'#6#1'*'#10'HistoryMax'#2#10#13'InputSelColor' + +#7#8'clPurple'#18'InputSelBackGround'#7#8'clSilver'#13'CaretInterval'#3#244#1 + +#23'GraphicalCharacterWidth'#2#10#10'AutoFollow'#9#0#0#6'TTimer'#11'ReaderTi' + +'mer'#8'Interval'#3#188#2#7'OnTimer'#7#16'ReaderTimerTimer'#4'left'#2'B'#3't' + +'op'#2'K'#0#0#6'TTimer'#12'ProcessTimer'#7'Enabled'#8#8'Interval'#2'd'#7'OnT' + +'imer'#7#17'ProcessTimerTimer'#4'left'#2'h'#3'top'#2'K'#0#0#0 +]); diff --git a/components/cmdline/wnmainform.pas b/components/cmdline/wnmainform.pas new file mode 100644 index 000000000..e9cc663cc --- /dev/null +++ b/components/cmdline/wnmainform.pas @@ -0,0 +1,239 @@ +{ Copyright (C) 2007 Julian Schutsch + + This source is free software; you can 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 code is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + A copy of the GNU General Public License is available on the World Wide Web + at . You can also obtain it by writing + to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + This Software is GPL, not LGPL as the libary it uses ! + + Changelog + 10.8.2007 : Added "Buttons" Unit to avoid "TButton" missing error on 0.9.22 (Linux) + +} +unit wnmainform; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, LResources, Forms, Graphics, Dialogs, ExtCtrls,LCLType, + ucmdbox, StdCtrls, Controls, Buttons; + +type + + { TWMainForm } + + TWMainForm = class(TForm) + Button1: TButton; + Button2: TButton; + Button3: TButton; + CmdBox: TCmdBox; + CbSetCaret: TComboBox; + Label1: TLabel; + HistoryList: TListBox; + RightPanel: TPanel; + Splitter1: TSplitter; + ReaderTimer: TTimer; + ProcessTimer: TTimer; + procedure Button1Click(Sender: TObject); + procedure Button2Click(Sender: TObject); + procedure Button3Click(Sender: TObject); + procedure CmdBoxInput(ACmdBox: TCmdBox; Input: String); + procedure CbSetCaretChange(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure ProcessTimerTimer(Sender: TObject); + procedure ReaderTimerTimer(Sender: TObject); + private + TextPosition : Integer; + DText : TStringList; + Rdpw : Boolean; + FProcess : Integer; + end; + +var WMainForm: TWMainForm; + + +implementation + +{ TWMainForm } + +procedure TWMainForm.ReaderTimerTimer(Sender: TObject); +var i:Integer; +begin + CmdBox.TextColors(clRed,clNavy); + for i:=0 to 0 do + begin + if TextPosition=DText.Count then + begin + CmdBox.ClearLine; + CmdBox.TextColor(clYellow); + CmdBox.Writeln(#27#10#196); + TextPosition := 0; + ReaderTimer.Enabled := False; + end; + end; +end; + +procedure TWMainForm.FormCreate(Sender: TObject); +begin + DoubleBuffered := True; + DText := TStringList.Create; + if FileExists('demotext.txt') then DText.LoadFromFile('demotext.txt'); + CmdBox.StartRead(clRed,clNavy,'>',clYellow,clNavy); + CmdBox.TextColors(clWhite,clNavy); + CmdBox.Writeln(#27#218#27#10#191); + CmdBox.Writeln(#27#179'Type "help" to see a short list of available commands.'#27#10#179); + CmdBox.Writeln(#27#217#27#10#217); +end; + +procedure TWMainForm.CmdBoxInput(ACmdBox: TCmdBox; Input: String); +var i:Integer; +begin + if rdpw then + begin + CmdBox.TextColors(clLime,clBlue); + CmdBox.Writeln('Your Secret Password : '+Input); + CmdBox.TextColors(clSilver,clNavy); + rdpw:=false; + end + else + begin + rdpw:=false; + Input:=LowerCase(Input); + if Input='help' then + begin + CmdBox.TextColors(clLime,clNavy); + CmdBox.Writeln(#27#218#27#197#128#0#27#194#27#10#191); + CmdBox.Writeln(#27#179' Command'#27#33#128#0#27#179' Explanation'#27#10#179); + CmdBox.Writeln(#27#195#27#197#128#0#27#198#27#10#180); + CmdBox.Writeln(#27#179' help'#27#33#128#0#27#179' Gives this list of Commands'#27#10#179); + CmdBox.Writeln(#27#179' clear'#27#33#128#0#27#179' Clears the Content of CmdBox'#27#10#179); + CmdBox.Writeln(#27#179' start'#27#33#128#0#27#179' Outputs the Content of Demotext.txt from the beginning'#27#10#179); + CmdBox.Writeln(#27#179' stop'#27#33#128#0#27#179' Stops output and resets to Start'#27#10#179); + CmdBox.Writeln(#27#179' pause'#27#33#128#0#27#179' Interrupts output'#27#10#179); + CmdBox.Writeln(#27#179' resume'#27#33#128#0#27#179' Resumes output from the last position'#27#10#179); + CmdBox.Writeln(#27#179' clearhistory'#27#33#128#0#27#179' Clears all history entries'#27#10#179); + CmdBox.Writeln(#27#179' readpwd'#27#33#128#0#27#179' Read a Password (just as a test)'#27#10#179); + CmdBox.Writeln(#27#179' exit'#27#33#128#0#27#179' Exit program'#27#10#179); + CmdBox.Writeln(#27#217#27#197#128#0#27#193#27#10#217); + CmdBox.TextColor(clSilver); + end else + if Input='readpwd' then + begin + rdpw:=true; + end else + if Input='clearhistory' then + begin + CmdBox.TextColor(clYellow); + CmdBox.Writeln('Clear History...'); + CmdBox.TextColor(clSilver); + CmdBox.ClearHistory; + end else + if Input='start' then + begin + TextPosition:=0; + ReaderTimer.Enabled:=true; + CmdBox.TextColors(clLime,clBlue); + CmdBox.Writeln('Start...'); + end else if Input='stop' then + begin + TextPosition:=0; + ReaderTimer.Enabled:=false; + CmdBox.TextColors(clRed,clBlue); + CmdBox.Writeln('Stop...'); + end else if Input='pause' then + begin + ReaderTimer.Enabled:=false; + CmdBox.TextColors(clPurple,clBlue); + CmdBox.Writeln('Pause...'); + end else if Input='resume' then + begin + ReaderTimer.Enabled:=true; + CmdBox.TextColors(clGreen,clBlue); + CmdBox.Writeln('Continue...'); + end else if Input='clear' then + begin + CmdBox.Clear; + end else if Input='exit' then close else + begin + CmdBox.TextColors(clYellow,ClRed); + CmdBox.Writeln('Invalid Command!'); + end; + end; + if rdpw then CmdBox.StartReadPassWord(clYellow,clNavy,'Pwd:',clLime,clNavy) else + CmdBox.StartRead(clRed,clNavy,'>',clYellow,clNavy); + HistoryList.Clear; + for i:=0 to CmdBox.HistoryCount-1 do HistoryList.Items.Add(CmdBox.History[i]); +end; + +procedure TWMainForm.CbSetCaretChange(Sender: TObject); +begin + case cbSetCaret.ItemIndex of + 0:CmdBox.CaretType := cartLine; + 1:CmdBox.CaretType := cartSubBar; + 2:CmdBox.CaretType := cartBigBar; + end; + CmdBox.SetFocus; +end; + +procedure TWMainForm.Button2Click(Sender: TObject); +begin + CmdBox.ClearHistory; + HistoryList.Clear; +end; + +procedure TWMainForm.Button3Click(Sender: TObject); +begin + FProcess:=0; + ProcessTimer.Enabled:=True; +end; + +procedure TWMainForm.Button1Click(Sender: TObject); +begin + Close; +end; + +procedure TWMainForm.FormDestroy(Sender: TObject); +begin + DText.Free; +end; + +procedure TWMainForm.ProcessTimerTimer(Sender: TObject); +begin + if FProcess=100 then + begin + CmdBox.ClearLine; + ProcessTimer.Enabled:=False; + end + else + begin + CmdBox.TextColors(clRed,clBlue); + CmdBox.Write('Processing ['+IntToStr(FProcess)+'%]'#13); + end; + Inc(FProcess); +end; + +initialization + {$I wnmainform.lrs} + +end. +