diff --git a/src/LICENSE b/src/LICENSE new file mode 100755 index 0000000..818433e --- /dev/null +++ b/src/LICENSE @@ -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 +. diff --git a/src/RcTreeWidget.cpp b/src/RcTreeWidget.cpp index ed4a196..1ad8842 100755 --- a/src/RcTreeWidget.cpp +++ b/src/RcTreeWidget.cpp @@ -45,18 +45,9 @@ void RcTreeWidget::slot_ShowPopMenu(const QPoint& pos) } QAction* action = menu->addAction(tr("Show File in Explorer"), this, [&]() { - QString path, cmd; - - path = QString("%1/%2").arg(m_rootDir).arg(curItem->data(0, Qt::ToolTipRole).toString()); - #ifdef _WIN32 - path = path.replace("/", "\\"); - cmd = QString("explorer.exe /select,%1").arg(path); - #else - path = path.replace("\\", "/"); - cmd = QString("open -R %1").arg(path); - #endif - QProcess process; - process.startDetached(cmd); + QString path = QString("%1/%2").arg(m_rootDir).arg(curItem->data(0, Qt::ToolTipRole).toString()); + showFileInExplorer(path); + }); //没有名称表示是对齐的item,不存在对应的文件,只是占位 diff --git a/src/RealCompare.pro b/src/RealCompare.pro index 005f2f9..1035414 100755 --- a/src/RealCompare.pro +++ b/src/RealCompare.pro @@ -3,7 +3,7 @@ LANGUAGE = C++ TARGET = Notepad-- -CONFIG += qt warn_on Release +CONFIG += qt warn_on Debug QT += core gui widgets concurrent network xmlpatterns @@ -46,7 +46,7 @@ TRANSLATIONS += realcompare_zh.ts } } unix{ -if(CONFIG(debug, debug|release)){ +if(CONFIG(debug, Debug|Release)){ LIBS += -L/home/yzw/build/CCNotePad/x64/Debug -lqmyedit_qt5 QMAKE_CXXFLAGS += -fopenmp diff --git a/src/RealCompare.qrc b/src/RealCompare.qrc index 7c0aac4..eb1a277 100755 --- a/src/RealCompare.qrc +++ b/src/RealCompare.qrc @@ -135,55 +135,6 @@ Resources/edit/styledeepblue/zoomin.png Resources/edit/styledeepblue/zoomout.png Resources/edit/styledeepblue/needsaveall.png - qss/black.qss - qss/psblack/add_bottom.png - qss/psblack/add_left.png - qss/psblack/add_right.png - qss/psblack/add_top.png - qss/psblack/branch_close.png - qss/psblack/branch_open.png - qss/psblack/calendar_nextmonth.png - qss/psblack/calendar_prevmonth.png - qss/psblack/checkbox_checked.png - qss/psblack/checkbox_checked_disable.png - qss/psblack/checkbox_parcial.png - qss/psblack/checkbox_parcial_disable.png - qss/psblack/checkbox_unchecked.png - qss/psblack/checkbox_unchecked_disable.png - qss/psblack/radiobutton_checked.png - qss/psblack/radiobutton_checked_disable.png - qss/psblack/radiobutton_unchecked.png - qss/psblack/radiobutton_unchecked_disable.png - Resources/edit/styledark/needsaveall.png - Resources/edit/styledark/needsavebar.png - Resources/edit/styledark/autosave.png - Resources/edit/styledark/bincmp.png - Resources/edit/styledark/clearsign.png - Resources/edit/styledark/closefile.png - Resources/edit/styledark/copy.png - Resources/edit/styledark/crlf.png - Resources/edit/styledark/cut.png - Resources/edit/styledark/dircompare.png - Resources/edit/styledark/filecompare.png - Resources/edit/styledark/find.png - Resources/edit/styledark/goto.png - Resources/edit/styledark/indentGuide.png - Resources/edit/styledark/mark.png - Resources/edit/styledark/newfile.png - Resources/edit/styledark/next.png - Resources/edit/styledark/openfile.png - Resources/edit/styledark/paste.png - Resources/edit/styledark/pre.png - Resources/edit/styledark/redo.png - Resources/edit/styledark/rename.png - Resources/edit/styledark/replace.png - Resources/edit/styledark/sign.png - Resources/edit/styledark/transcode.png - Resources/edit/styledark/undo.png - Resources/edit/styledark/white.png - Resources/edit/styledark/zoomin.png - Resources/edit/styledark/zoomout.png - Resources/edit/styledark/closeall.png Resources/img/savedark.png Resources/img/opendark.png Resources/img/reloaddark.png @@ -193,5 +144,6 @@ Resources/img/diffall.png Resources/img/expand.png Resources/img/fold.png + qss/common.qss diff --git a/src/RealCompare.rc b/src/RealCompare.rc index 93ef05d..dfe696a 100755 Binary files a/src/RealCompare.rc and b/src/RealCompare.rc differ diff --git a/src/RealCompare.vcxproj b/src/RealCompare.vcxproj index f64793d..abe6aa6 100755 --- a/src/RealCompare.vcxproj +++ b/src/RealCompare.vcxproj @@ -20,7 +20,7 @@ v141 - x64\Release\ + x64\Debug\ false NotSet Application @@ -44,11 +44,11 @@ - x64\Debug\debug\Notepad--truex64\Release\release\Notepad--truefalse5.15.2_msvc2019_64core;network;gui;xmlpatterns;widgets;concurrent5.15.2_msvc2019_64core;network;gui;xmlpatterns;widgets;concurrent + x64\Debug\debug\Notepad--truex64\Debug\release\Notepad--truefalse5.12.10_msvc2017_64core;network;gui;xmlpatterns;widgets;concurrent5.12.10_msvc2017_64core;network;gui;xmlpatterns;widgets;concurrent - GeneratedFiles\$(ConfigurationName);GeneratedFiles;.;qscint\src;qscint\src\Qsci;qscint\scintilla\include;cceditor;x64\Release;release;/include;%(AdditionalIncludeDirectories) + GeneratedFiles\$(ConfigurationName);GeneratedFiles;.;qscint\src;qscint\src\Qsci;qscint\scintilla\include;cceditor;./x64/Release;release;/include;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions) release\ false @@ -57,7 +57,7 @@ Sync release\ MaxSpeed - _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;QSCINTILLA_DLL;NDEBUG;QT_NO_DEBUG;%(PreprocessorDefinitions) + _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;QT_NO_DEBUG;NDEBUG;%(PreprocessorDefinitions) false MultiThreadedDLL @@ -66,14 +66,13 @@ Level3 true - qmyedit_qt5.lib;shell32.lib;%(AdditionalDependencies) - x64\Release;C:\openssl\lib;C:\Utils\my_sql\mysql-5.7.25-winx64\lib;C:\Utils\postgresql\pgsql\lib;%(AdditionalLibraryDirectories) + qmyedit_qt5d.lib;shell32.lib;%(AdditionalDependencies) + x64\Debug;C:\openssl\lib;C:\Utils\my_sql\mysql-5.6.11-winx64\lib;C:\Utils\postgresql\pgsql\lib;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true false true false - true $(OutDir)\Notepad--.exe true Windows @@ -85,12 +84,12 @@ 0 - _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;QSCINTILLA_DLL;NDEBUG;QT_NO_DEBUG;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CONCURRENT_LIB;QT_XMLPATTERNS_LIB;QT_NETWORK_LIB;QT_CORE_LIB;%(PreprocessorDefinitions) + _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;QT_NO_DEBUG;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CONCURRENT_LIB;QT_XMLPATTERNS_LIB;QT_NETWORK_LIB;QT_CORE_LIB;%(PreprocessorDefinitions) msvc./$(Configuration)/moc_predefs.hMoc'ing %(Identity)...output$(Configuration)moc_%(Filename).cppRealComparedefaultRcc'ing %(Identity)...$(Configuration)qrc_%(Filename).cppUic'ing %(Identity)...$(ProjectDir)ui_%(Filename).h - GeneratedFiles\$(ConfigurationName);GeneratedFiles;.;qscint\src;qscint\src\Qsci;qscint\scintilla\include;cceditor;x64\Release;debug;/include;%(AdditionalIncludeDirectories) + GeneratedFiles\$(ConfigurationName);GeneratedFiles;.;qscint\src;qscint\src\Qsci;qscint\scintilla\include;cceditor;./x64/Release;debug;/include;%(AdditionalIncludeDirectories) -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions) debug\ false @@ -99,7 +98,7 @@ Sync debug\ Disabled - _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;QSCINTILLA_DLL;%(PreprocessorDefinitions) + _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions) false MultiThreadedDebugDLL true @@ -107,8 +106,8 @@ Level3 true - x64\Debug\qmyedit_qt5d.lib;shell32.lib;%(AdditionalDependencies) - x64\Debug;C:\openssl\lib;C:\Utils\my_sql\mysql-5.7.25-winx64\lib;C:\Utils\postgresql\pgsql\lib;%(AdditionalLibraryDirectories) + qmyedit_qt5d.lib;shell32.lib;%(AdditionalDependencies) + x64\Debug;C:\openssl\lib;C:\Utils\my_sql\mysql-5.6.11-winx64\lib;C:\Utils\postgresql\pgsql\lib;%(AdditionalLibraryDirectories) "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true true @@ -124,7 +123,7 @@ 0 - _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;QSCINTILLA_DLL;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CONCURRENT_LIB;QT_XMLPATTERNS_LIB;QT_NETWORK_LIB;QT_CORE_LIB;_DEBUG;%(PreprocessorDefinitions) + _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CONCURRENT_LIB;QT_XMLPATTERNS_LIB;QT_NETWORK_LIB;QT_CORE_LIB;_DEBUG;%(PreprocessorDefinitions) msvc./$(Configuration)/moc_predefs.hMoc'ing %(Identity)...output$(Configuration)moc_%(Filename).cppRealComparedefaultRcc'ing %(Identity)...$(Configuration)qrc_%(Filename).cppUic'ing %(Identity)...$(ProjectDir)ui_%(Filename).h @@ -135,6 +134,8 @@ + + @@ -148,6 +149,7 @@ + @@ -162,6 +164,8 @@ + + @@ -220,6 +224,26 @@ + + + + + + + + + + + + + + + + + + + + @@ -324,6 +348,16 @@ + + + + + + + + + + @@ -436,6 +470,18 @@ + + + + + + + + + + + + @@ -532,31 +578,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - @@ -601,6 +622,14 @@ + + + + + + + + @@ -666,6 +695,10 @@ + + + + @@ -686,6 +719,28 @@ + + + + + + + + + + + + + + + + + + + + + + @@ -785,6 +840,17 @@ + + + + + + + + + + + @@ -884,6 +950,17 @@ + + + + + + + + + + + @@ -972,34 +1049,16 @@ - - - - - - - - - - - - - - - - - - @@ -1010,9 +1069,7 @@ - - @@ -1020,35 +1077,28 @@ - + - - - - - - - @@ -1057,7 +1107,6 @@ - @@ -1065,14 +1114,10 @@ - - - - @@ -1086,24 +1131,16 @@ - - - - - - - - @@ -1113,10 +1150,8 @@ - - @@ -1129,16 +1164,13 @@ - - - @@ -1146,15 +1178,12 @@ - - - diff --git a/src/RealCompare.vcxproj.filters b/src/RealCompare.vcxproj.filters index 536ad83..e534af7 100755 --- a/src/RealCompare.vcxproj.filters +++ b/src/RealCompare.vcxproj.filters @@ -78,6 +78,12 @@ Source Files + + Source Files + + + Source Files + Source Files @@ -117,6 +123,9 @@ Source Files + + Source Files + Source Files @@ -159,6 +168,12 @@ Source Files + + Source Files + + + Source Files + Source Files @@ -224,6 +239,12 @@ Header Files + + Header Files + + + Header Files + Header Files @@ -266,6 +287,9 @@ Header Files + + Header Files + Header Files @@ -305,6 +329,15 @@ Header Files + + Header Files + + + Header Files + + + Header Files + Header Files @@ -347,31 +380,6 @@ Header Files - - - - - - - - - - - - - - - - - - - - - - - - - Header Files @@ -418,6 +426,14 @@ + + + + + + + + @@ -473,6 +489,10 @@ + + + + @@ -488,6 +508,12 @@ Form Files + + Form Files + + + Form Files + Form Files @@ -515,6 +541,9 @@ Form Files + + Form Files + Form Files @@ -542,6 +571,9 @@ Form Files + + Form Files + Form Files @@ -589,30 +621,15 @@ Resource Files - - Resource Files - - - Resource Files - - - Resource Files - Resource Files - - Resource Files - Resource Files Resource Files - - Resource Files - Resource Files @@ -622,57 +639,18 @@ Resource Files - - Resource Files - Resource Files - - Resource Files - Resource Files - - Resource Files - - - Resource Files - Resource Files - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - Resource Files - - Resource Files - Resource Files @@ -703,15 +681,9 @@ Resource Files - - Resource Files - Resource Files - - Resource Files - Resource Files @@ -733,7 +705,7 @@ Resource Files - + Resource Files @@ -742,15 +714,9 @@ Resource Files - - Resource Files - Resource Files - - Resource Files - Resource Files @@ -769,9 +735,6 @@ Resource Files - - Resource Files - Resource Files @@ -784,15 +747,9 @@ Resource Files - - Resource Files - Resource Files - - Resource Files - Resource Files @@ -808,18 +765,12 @@ Resource Files - - Resource Files - Resource Files Resource Files - - Resource Files - Resource Files @@ -844,9 +795,6 @@ Resource Files - - Resource Files - Resource Files @@ -868,30 +816,18 @@ Resource Files - - Resource Files - Resource Files - - Resource Files - Resource Files Resource Files - - Resource Files - Resource Files - - Resource Files - Resource Files @@ -931,15 +867,9 @@ Resource Files - - Resource Files - Resource Files - - Resource Files - Resource Files @@ -949,9 +879,6 @@ Resource Files - - Resource Files - Resource Files @@ -967,24 +894,9 @@ Resource Files - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - Resource Files - - Resource Files - Resource Files @@ -1012,18 +924,12 @@ Resource Files - - Resource Files - Resource Files Resource Files - - Resource Files - Resource Files @@ -1060,9 +966,6 @@ Resource Files - - Resource Files - Resource Files @@ -1081,15 +984,9 @@ Resource Files - - Resource Files - Resource Files - - Resource Files - Resource Files @@ -1111,9 +1008,6 @@ Resource Files - - Resource Files - Resource Files @@ -1126,18 +1020,12 @@ Resource Files - - Resource Files - Resource Files Resource Files - - Resource Files - Resource Files diff --git a/src/RealCompare.vcxproj.user b/src/RealCompare.vcxproj.user index 13f7103..5761481 100755 --- a/src/RealCompare.vcxproj.user +++ b/src/RealCompare.vcxproj.user @@ -2,9 +2,9 @@ - 2022-12-11T10:37:19.8112403Z + 2023-01-07T07:01:11.4235283Z - 2022-12-11T10:37:20.2889680Z + 2023-01-07T07:01:11.5050188Z \ No newline at end of file diff --git a/src/batchfindreplace.cpp b/src/batchfindreplace.cpp new file mode 100755 index 0000000..cb071c3 --- /dev/null +++ b/src/batchfindreplace.cpp @@ -0,0 +1,370 @@ +#include "batchfindreplace.h" +#include "scintillaeditview.h" +#include "ccnotepad.h" +#include "progresswin.h" + +#include +#include + +BatchFindReplace::BatchFindReplace(QWidget *parent) + : QMainWindow(parent), m_curEditWin(nullptr), m_editTabWidget(nullptr) +{ + ui.setupUi(this); + + m_mainNotepad = dynamic_cast(parent); +} + +BatchFindReplace::~BatchFindReplace() +{} + +void BatchFindReplace::setTabWidget(QTabWidget* editTabWidget) +{ + m_editTabWidget = editTabWidget; +} + +//Զǰڵ״̬˱仯Ҫ϶Ϊ״β +QWidget* BatchFindReplace::autoAdjustCurrentEditWin() +{ + QWidget* pw = m_editTabWidget->currentWidget(); + + if (m_curEditWin != pw) + { + m_curEditWin = pw; + } + return pw; +} + +void BatchFindReplace::appendToFindTable(QString findKeyword) +{ + int rNum = ui.findReplaceTable->rowCount(); + ui.findReplaceTable->insertRow(rNum); + + QTableWidgetItem* itemFind = new QTableWidgetItem(findKeyword); + ui.findReplaceTable->setItem(rNum, 0, itemFind); + ui.findReplaceTable->setItem(rNum, 1, new QTableWidgetItem()); +} + +//ﲻ׷ӣDz룬ӦItemѾڡ򲻲 +void BatchFindReplace::insertToReplaceTable(int row, QString replaceKeyword) +{ + QTableWidgetItem* item = ui.findReplaceTable->item(row, 1); + if (item == nullptr) + { + ui.statusBar->showMessage(tr("$1 has no find match work item").arg(replaceKeyword)); + return; + } + + item->setText(replaceKeyword); +} + +void BatchFindReplace::insertToFindReplaceTable(QStringList& replaceKeyword) +{ + for (int i = 0; i < replaceKeyword.size(); ++i) + { + insertToReplaceTable(i, replaceKeyword.at(i)); + } +} + + +void BatchFindReplace::appendToFindReplaceTable(QStringList& findKeyword) +{ + if (findKeyword.isEmpty()) + { + return; + } + + int rNum = ui.findReplaceTable->rowCount(); + + for (int i = 0; i < findKeyword.size(); ++i) + { + int curRow = rNum + i; + ui.findReplaceTable->insertRow(curRow); + + QTableWidgetItem* itemFind = new QTableWidgetItem(findKeyword.at(i)); + ui.findReplaceTable->setItem(curRow, 0, itemFind); + ui.findReplaceTable->setItem(curRow, 1, new QTableWidgetItem()); + } +} + +bool BatchFindReplace::tranInputKeyword(QString& findKeyWord, QStringList& outputKeyWordList) +{ + //ѿհַո\t \r\n ַ滻Ϊո + QRegExp re("\\s"); + findKeyWord.replace(re, QString(" ")); + + //ٽпոָ + outputKeyWordList = findKeyWord.split(" "); + + if (outputKeyWordList.size() > 20000) + { + ui.statusBar->showMessage(tr("Max find key word 20000 !"), 10000); + return false; + } + + //ɾÿһյԪ + for (int i = outputKeyWordList.size() - 1; i >= 0; --i) + { + if (outputKeyWordList[i].trimmed().isEmpty()) + { + outputKeyWordList.removeAt(i); + } + } + + if (outputKeyWordList.isEmpty()) + { + return false; + } + + return true; +} + +void BatchFindReplace::on_freshBtClick() +{ + QStringList findWordList; + QString findKeyWord = ui.findKeywordEdit->toPlainText(); + if (findKeyWord.isEmpty()) + { + ui.statusBar->showMessage(tr("Please input find keyword !"),10000); + + if (ui.findReplaceTable->rowCount() > 0) + { + ui.findReplaceTable->clearContents(); + ui.findReplaceTable->setRowCount(0); + } + return; + } + + if (!tranInputKeyword(findKeyWord, findWordList)) + { + return; + } + else + { + ui.findReplaceTable->clearContents(); + ui.findReplaceTable->setRowCount(0); + appendToFindReplaceTable(findWordList); + } + + QStringList replaceWordList; + QString replaceKeyWord = ui.replaceKeywordEdit->toPlainText(); + if (!tranInputKeyword(replaceKeyWord, replaceWordList)) + { + return; + } + else + { + insertToFindReplaceTable(replaceWordList); + } +} + +//ҹ +void BatchFindReplace::on_findBtClick() +{ + if (m_mainNotepad != nullptr && m_mainNotepad) + { + int rowNums = ui.findReplaceTable->rowCount(); + + if (rowNums == 0) + { + return; + } + ProgressWin* loadFileProcessWin = new ProgressWin(this); + + loadFileProcessWin->setWindowModality(Qt::WindowModal); + + loadFileProcessWin->info(tr("total %1 keyword, please wait ...").arg(rowNums)); + + loadFileProcessWin->setTotalSteps(rowNums); + + loadFileProcessWin->show(); + + int foundTimes = 0; + + for (int i = 0; i < rowNums; ++i) + { + QTableWidgetItem* item = ui.findReplaceTable->item(i, 0); + if (item != nullptr && !item->text().isEmpty()) + { + if (loadFileProcessWin->isCancel()) + { + break; + } + + foundTimes += m_mainNotepad->findAtBack(item->text()); + + loadFileProcessWin->moveStep(); + + QCoreApplication::processEvents(); + } + } + + delete loadFileProcessWin; + + ui.statusBar->showMessage(tr("Batch Find Finished! total %1 found.").arg(foundTimes),10000); + } +} + +//滻 +void BatchFindReplace::on_replaceBtClick() +{ + if (m_mainNotepad != nullptr && m_mainNotepad) + { + int rowNums = ui.findReplaceTable->rowCount(); + + int replaceTimes = 0; + + QStringList findKeyList; + QStringList replaceKeyList; + + for (int i = 0; i < rowNums; ++i) + { + QTableWidgetItem* item = ui.findReplaceTable->item(i, 0); + if (item != nullptr && !item->text().isEmpty()) + { + QTableWidgetItem* replaceItem = ui.findReplaceTable->item(i, 1); + if (replaceItem != nullptr) + { + if (item->text() != replaceItem->text()) + { + findKeyList.append(item->text()); + replaceKeyList.append(replaceItem->text()); + } + } + } + } + replaceTimes = m_mainNotepad->replaceAtBack(findKeyList, replaceKeyList); + + ui.statusBar->showMessage(tr("Batch Replace Finished, total Replace %1 times !").arg(replaceTimes), 10000); + } +} + +void BatchFindReplace::on_swapFindReplace() +{ + QString findText = ui.findKeywordEdit->toPlainText(); + QString replaceText = ui.replaceKeywordEdit->toPlainText(); + + ui.findKeywordEdit->setPlainText(replaceText); + ui.replaceKeywordEdit->setPlainText(findText); + + on_freshBtClick(); +} + +void BatchFindReplace::on_export() +{ + QString filter("Text files (*.txt);;All types(*.*)"); + QString fileName = QFileDialog::getSaveFileName(this, tr("Save File As ..."), QString(), filter); + + if (!fileName.isEmpty()) + { + QSettings setting(fileName, QSettings::IniFormat); + setting.setIniCodec("UTF-8"); + + int rowNums = ui.findReplaceTable->rowCount(); + + QStringList findList; + QStringList replaceList; + + for (int i = 0; i < rowNums; ++i) + { + QTableWidgetItem* item = ui.findReplaceTable->item(i, 0); + if (item != nullptr && !item->text().isEmpty()) + { + QTableWidgetItem* replaceItem = ui.findReplaceTable->item(i, 1); + if (replaceItem != nullptr) + { + findList.append(item->text()); + replaceList.append(replaceItem->text()); + } + } + } + + if (!findList.isEmpty()) + { + setting.setValue("find", findList); + setting.setValue("replace", replaceList); + + ui.statusBar->showMessage(tr("Export File finished !"), 10000); + } + else + { + ui.statusBar->showMessage(tr("No Content to Export !"), 10000); + } + } +} + +void BatchFindReplace::on_import() +{ + QFileDialog fd(this, QString(), CCNotePad::s_lastOpenDirPath); + fd.setFileMode(QFileDialog::ExistingFile); + + if (fd.exec() == QDialog::Accepted) //ɹִ + { + QStringList fileNameList = fd.selectedFiles(); //ļб + QFileInfo fi(fileNameList[0]); + + QSettings setting(fi.filePath(), QSettings::IniFormat); + setting.setIniCodec("UTF-8"); + + ui.findKeywordEdit->setPlainText(setting.value("find").toStringList().join(" ")); + ui.replaceKeywordEdit->setPlainText(setting.value("replace").toStringList().join(" ")); + + on_freshBtClick(); + } + else + { + fd.close(); + } +} + +void BatchFindReplace::on_mark() +{ + if (m_mainNotepad != nullptr) + { + int rowNums = ui.findReplaceTable->rowCount(); + if (rowNums == 0) + { + return; + } + + int markTimes = 0; + + ProgressWin* loadFileProcessWin = new ProgressWin(this); + + loadFileProcessWin->setWindowModality(Qt::WindowModal); + + loadFileProcessWin->info(tr("total %1 keyword, please wait ...").arg(rowNums)); + + loadFileProcessWin->setTotalSteps(rowNums); + + loadFileProcessWin->show(); + + for (int i = 0; i < rowNums; ++i) + { + QTableWidgetItem* item = ui.findReplaceTable->item(i, 0); + if (item != nullptr && !item->text().isEmpty()) + { + if (loadFileProcessWin->isCancel()) + { + break; + } + + markTimes += m_mainNotepad->markAtBack(item->text()); + + loadFileProcessWin->moveStep(); + + QCoreApplication::processEvents(); + } + } + + delete loadFileProcessWin; + ui.statusBar->showMessage(tr("Batch Mark Finished, total Mark %1 times !").arg(markTimes), 10000); + } +} + +void BatchFindReplace::on_clearMark() +{ + if (m_mainNotepad != nullptr) + { + m_mainNotepad->slot_clearMark(); + } +} diff --git a/src/batchfindreplace.h b/src/batchfindreplace.h new file mode 100755 index 0000000..740209d --- /dev/null +++ b/src/batchfindreplace.h @@ -0,0 +1,43 @@ +#pragma once + +#include +#include +#include "ui_batchfindreplace.h" + +class CCNotePad; + +class BatchFindReplace : public QMainWindow +{ + Q_OBJECT + +public: + BatchFindReplace(QWidget *parent = nullptr); + virtual ~BatchFindReplace(); + void setTabWidget(QTabWidget* editTabWidget); + +private slots: + void on_freshBtClick(); + void on_findBtClick(); + void on_replaceBtClick(); + void on_swapFindReplace(); + void on_export(); + void on_import(); + void on_mark(); + void on_clearMark(); + +private: + bool tranInputKeyword(QString& keyWord, QStringList& outputKeyWordList); + void appendToFindReplaceTable(QStringList& findKeyword); + void appendToFindTable(QString findKeyword); + void insertToReplaceTable(int row, QString replaceKeyword); + void insertToFindReplaceTable(QStringList& replaceKeyword); + + QWidget* autoAdjustCurrentEditWin(); +private: + Ui::BatchFindReplaceClass ui; + + QTabWidget* m_editTabWidget; + QWidget* m_curEditWin; + + CCNotePad* m_mainNotepad; +}; diff --git a/src/batchfindreplace.ui b/src/batchfindreplace.ui new file mode 100755 index 0000000..e644c09 --- /dev/null +++ b/src/batchfindreplace.ui @@ -0,0 +1,319 @@ + + + BatchFindReplaceClass + + + + 0 + 0 + 902 + 737 + + + + BatchFindReplace + + + + + 3 + + + 6 + + + 3 + + + 3 + + + + + + + + + Enter multiple find keywords, separated by blank characters + + + + + + + + + + + + + + Enter multiple Replace keywords, separated by blank characters + + + + + + + + + + + + + + true + + + + Keyword + + + + + Replace + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Fresh + + + + + + + swap + + + + + + + Find + + + + + + + Replace + + + + + + + Mark + + + + + + + ClearMark + + + + + + + Import + + + + + + + Export + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + TopToolBarArea + + + false + + + + + + + + + freshBt + clicked() + BatchFindReplaceClass + on_freshBtClick() + + + 204 + 710 + + + 218 + 703 + + + + + findBt + clicked() + BatchFindReplaceClass + on_findBtClick() + + + 366 + 710 + + + 426 + 736 + + + + + replaceBt + clicked() + BatchFindReplaceClass + on_replaceBtClick() + + + 447 + 710 + + + 530 + 709 + + + + + swapBt + clicked() + BatchFindReplaceClass + on_swapFindReplace() + + + 285 + 710 + + + 378 + 736 + + + + + importBt + clicked() + BatchFindReplaceClass + on_import() + + + 690 + 710 + + + 687 + 736 + + + + + exportBt + clicked() + BatchFindReplaceClass + on_export() + + + 771 + 710 + + + 799 + 698 + + + + + markBt + clicked() + BatchFindReplaceClass + on_mark() + + + 528 + 710 + + + 584 + 742 + + + + + pushButton + clicked() + BatchFindReplaceClass + on_clearMark() + + + 577 + 693 + + + 570 + 746 + + + + + + on_freshBtClick() + on_findBtClick() + on_replaceBtClick() + on_swapFindReplace() + on_import() + on_export() + on_mark() + on_clearMark() + + diff --git a/src/bigfilemessage.cpp b/src/bigfilemessage.cpp new file mode 100755 index 0000000..1537e4d --- /dev/null +++ b/src/bigfilemessage.cpp @@ -0,0 +1,39 @@ +#include "bigfilemessage.h" + +BigFileMessage::BigFileMessage(QWidget *parent) + : QDialog(parent), m_result(-1) +{ + ui.setupUi(this); +} + +BigFileMessage::~BigFileMessage() +{} + + +void BigFileMessage::setTip(QString msg) +{ + ui.label->setText(msg); +} + +void BigFileMessage::slot_okBt() +{ + if (ui.textMode->isChecked()) + { + m_result = 0; + } + else if(ui.bigTextMode->isChecked()) + { + m_result = 1; + } + else if (ui.hexMode->isChecked()) + { + m_result = 2; + } + done(m_result); +} + +void BigFileMessage::slot_cancelBt() +{ + m_result = -1; + done(m_result); +} \ No newline at end of file diff --git a/src/bigfilemessage.h b/src/bigfilemessage.h new file mode 100755 index 0000000..d036bd4 --- /dev/null +++ b/src/bigfilemessage.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include +#include "ui_bigfilemessage.h" + +class BigFileMessage : public QDialog +{ + Q_OBJECT + +public: + BigFileMessage(QWidget *parent = nullptr); + ~BigFileMessage(); + void setTip(QString msg); + +private slots: + void slot_okBt(); + void slot_cancelBt(); + +private: + Ui::BigFileMessageClass ui; + int m_result; +}; diff --git a/src/bigfilemessage.ui b/src/bigfilemessage.ui new file mode 100755 index 0000000..f914b24 --- /dev/null +++ b/src/bigfilemessage.ui @@ -0,0 +1,163 @@ + + + BigFileMessageClass + + + + 0 + 0 + 509 + 203 + + + + BigFileMessage + + + + 3 + + + 3 + + + 3 + + + 6 + + + + + TextLabel + + + + + + + Open Mode + + + + + + Text Mode + + + + + + + Open directly in text mode.May be slow, Need wait. + + + + + + + Big Text + + + true + + + + + + + Read only open, load in blocks, and turn pages manually. + + + + + + + Hex Bin + + + + + + + Binary Open,load in blocks, and turn pages manually. + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Ok + + + + + + + Cancel + + + + + + + + + + + + okBt + clicked() + BigFileMessageClass + slot_okBt() + + + 359 + 168 + + + 284 + 193 + + + + + cancelBt + clicked() + BigFileMessageClass + slot_cancelBt() + + + 448 + 176 + + + 446 + 196 + + + + + + slot_okBt() + slot_cancelBt() + + diff --git a/src/cceditor/ccnotepad.cpp b/src/cceditor/ccnotepad.cpp index faca6f5..1f04879 100755 --- a/src/cceditor/ccnotepad.cpp +++ b/src/cceditor/ccnotepad.cpp @@ -19,6 +19,12 @@ #include "langstyledefine.h" #include "extlexermanager.h" #include "aboutndd.h" +#include "filelistview.h" +#include "bigfilemessage.h" +#include "batchfindreplace.h" +#include "pluginmgr.h" +#include "plugin.h" +#include "pluginGl.h" #include @@ -48,6 +54,8 @@ #include #include #include +#include +#include #include "Sorters.h" @@ -329,6 +337,7 @@ const char *GotoHexIcon32 = ":/Resources/edit/styledeepblue/goto.png"; //const char *TabNeedSave32 = ":/Resources/edit/global/needsave.png"; //const char *TabNoNeedSave32 = ":/Resources/edit/global/noneedsave.png"; +#if 0 const char *NewFileIconDark32 = ":/Resources/edit/styledark/newfile.png"; const char *OpenFileIconDark32 = ":/Resources/edit/styledark/openfile.png"; const char *NeedSaveBarIconDark32 = ":/Resources/edit/styledark/needsavebar.png"; @@ -363,6 +372,11 @@ const char *NextHexIconDark32 = ":/Resources/edit/styledark/next.png"; const char *GotoHexIconDark32 = ":/Resources/edit/styledark/goto.png"; const char *TabNeedSaveDark32 = ":/Resources/edit/global/needsave.png"; const char *TabNoNeedSaveDark32 = ":/Resources/edit/global/noneedsavedark.png"; +#endif + +const char *TabNeedSaveDark32 = ":/notepad/needsave.png"; +const char *TabNoNeedSaveDark32 = ":/notepad/noneedsave.png"; + #ifdef STYLE_NOTEPAD const char* NewFileIcon = ":/notepad/newFile.png"; @@ -416,6 +430,7 @@ int CCNotePad::s_showblank = 0; //显示空白 int CCNotePad::s_restoreLastFile = 1;//自动恢复上次打开的文件 int CCNotePad::s_curStyleId = 0; int CCNotePad::s_curMarkColorId = SCE_UNIVERSAL_FOUND_STYLE_EXT5; +int CCNotePad::s_hightWebAddr = 0; //lexerName to index @@ -974,11 +989,10 @@ LexerInfo CCNotePad::getLangLexerIdByFileExt(QString filePath) CCNotePad::CCNotePad(bool isMainWindows, QWidget *parent) : QMainWindow(parent), m_cutFile(nullptr),m_copyFile(nullptr), m_dockSelectTreeWin(nullptr), \ m_pResultWin(nullptr),m_isQuitCancel(false), m_tabRightClickMenu(nullptr), m_shareMem(nullptr),m_isMainWindows(isMainWindows),\ - m_openInNewWinAct(nullptr), m_showFileDirAct(nullptr), m_timerAutoSave(nullptr), m_curColorIndex(-1) + m_openInNewWinAct(nullptr), m_showFileDirAct(nullptr), m_timerAutoSave(nullptr), m_curColorIndex(-1), m_fileListView(nullptr), m_isInReloadFile(false) { ui.setupUi(this); - #ifdef Q_OS_MAC setWindowIcon(QIcon(":/mac.icns")); #endif @@ -1151,16 +1165,22 @@ void CCNotePad::quickshow() m_lineNumLabel = new QLabel(tr("Ln:0 Col:0"), ui.statusBar); m_langDescLabel = new QLabel("Txt", ui.statusBar); + + m_zoomLabel = new QLabel("Zoom", ui.statusBar); + m_codeStatusLabel->setMinimumWidth(120); m_lineEndLabel->setMinimumWidth(100); m_lineNumLabel->setMinimumWidth(120); m_langDescLabel->setMinimumWidth(100); + m_zoomLabel->setMinimumWidth(100); //0在前面,越小越在左边 - ui.statusBar->insertPermanentWidget(0, m_langDescLabel); - ui.statusBar->insertPermanentWidget(1, m_lineNumLabel); - ui.statusBar->insertPermanentWidget(2, m_lineEndLabel); - ui.statusBar->insertPermanentWidget(3, m_codeStatusLabel); + ui.statusBar->insertPermanentWidget(0, m_zoomLabel); + ui.statusBar->insertPermanentWidget(1, m_langDescLabel); + ui.statusBar->insertPermanentWidget(2, m_lineNumLabel); + ui.statusBar->insertPermanentWidget(3, m_lineEndLabel); + ui.statusBar->insertPermanentWidget(4, m_codeStatusLabel); + initToolBar(); @@ -1174,8 +1194,8 @@ void CCNotePad::quickshow() m_quitAction = ui.menuFile->addAction(tr("Quit"), this, &CCNotePad::slot_quit); m_quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q)); - connect(ui.editTabWidget, &QTabWidget::currentChanged, this, &CCNotePad::slot_tabCurrentChanged); - connect(ui.editTabWidget, &QTabWidget::tabBarClicked, this, &CCNotePad::slot_tabBarClicked); + connect(ui.editTabWidget, &QTabWidget::currentChanged, this, &CCNotePad::slot_tabCurrentChanged, Qt::UniqueConnection); + connect(ui.editTabWidget, &QTabWidget::tabBarClicked, this, &CCNotePad::slot_tabBarClicked, Qt::QueuedConnection); ui.editTabWidget->installEventFilter(this); m_fileWatch = new QFileSystemWatcher(this); @@ -1193,13 +1213,171 @@ void CCNotePad::quickshow() } + m_isInitBookMarkAct = false; + slot_loadBookMarkMenu(); slot_loadMarkColor(); + m_isToolMenuLoaded = false; + init_toolsMenu(); + + this->setContextMenuPolicy(Qt::NoContextMenu); + + //恢复文件列表 + if (1 == NddSetting::getKeyValueFromNumSets(FILELISTSHOW)) + { + initFileListDockWin(); } + //隐藏工具栏 + if (0 == NddSetting::getKeyValueFromNumSets(TOOLBARSHOW)) + { + ui.mainToolBar->setVisible(false); + ui.actionShow_ToolBar->setChecked(false); + } + //高亮web地址。默认为0不高亮 + if (1 == NddSetting::getKeyValueFromNumSets(SHOWWEBADDR)) + { + s_hightWebAddr = 1; + ui.actionShow_Web_Addr->setChecked(true); + } +} + +void CCNotePad::init_toolsMenu() +{ + connect(ui.menuTools,&QMenu::aboutToShow,this,&CCNotePad::slot_dynamicLoadToolMenu); +} + +enum ToolMenuAct { + BATCH_FIND = 1, +}; +//动态加载工具菜单项 +void CCNotePad::slot_dynamicLoadToolMenu() +{ + if (!m_isToolMenuLoaded) + { + m_isToolMenuLoaded = true; + + ui.menuTools->addAction(tr("Plugin Manager"), this, &CCNotePad::slot_pluginMgr); + + QMenu* formatMenu = new QMenu(tr("Format Language"), this); + formatMenu->addAction(tr("Format Xml"), this, &CCNotePad::slot_formatXml); + formatMenu->addAction(tr("Format Json"), this, &CCNotePad::slot_formatJson); + ui.menuTools->addMenu(formatMenu); + + QAction* pAct = nullptr; + pAct = ui.menuTools->addAction(tr("Batch Find"), this, &CCNotePad::slot_batchFind); + pAct->setData(BATCH_FIND); + + //动态加载插件 + loadPluginLib(); + } +} + +void CCNotePad::slot_pluginMgr() +{ + PluginMgr* pWin = new PluginMgr(this, m_pluginList); + pWin->setAttribute(Qt::WA_DeleteOnClose); + pWin->show(); +} + +void CCNotePad::loadPluginLib() +{ + QString strDir = qApp->applicationDirPath(); + QDir dir(strDir); + if (dir.cd("./plugin")) + { + strDir = dir.absolutePath(); + + loadPluginProcs(strDir,ui.menuTools); + } +} + +void CCNotePad::onPlugFound(NDD_PROC_DATA& procData, QMenu* pUserData) +{ + QMenu* pMenu = pUserData; + + if (pMenu == NULL) + { + return; + } + + QAction* pAction = new QAction(pMenu); + pAction->setText(procData.m_strPlugName); + pAction->setData(procData.m_strFilePath); + pMenu->addAction(pAction); + connect(pAction, &QAction::triggered, this, &CCNotePad::onPlugWork); + + m_pluginList.append(procData); +} + +//真正执行插件的工作 +void CCNotePad::onPlugWork(bool check) +{ + QAction* pAct = dynamic_cast(sender()); + if (pAct != nullptr) + { + QString plugPath = pAct->data().toString(); + + QLibrary* pLib = new QLibrary(plugPath); + + NDD_PROC_MAIN_CALLBACK pMainCallBack; + pMainCallBack = (NDD_PROC_MAIN_CALLBACK)pLib->resolve("NDD_PROC_MAIN"); + + if (pMainCallBack != NULL) + { + std::function foundCallBack = std::bind(&CCNotePad::getCurEditView, this); + + pMainCallBack(this, plugPath, foundCallBack); + } + else + { + ui.statusBar->showMessage(tr("plugin %1 load failed !").arg(plugPath), 10000); + } + + } +} + +void CCNotePad::loadPluginProcs(QString strLibDir, QMenu* pMenu) +{ + QMenu* pSubMenu = new QMenu(tr("Plugin"), pMenu); + + std::function foundCallBack = std::bind(&CCNotePad::onPlugFound, this, std::placeholders::_1, std::placeholders::_2); + + int nRet = loadProc(strLibDir, foundCallBack, pSubMenu); + + if (nRet > 0) + { + pMenu->addMenu(pSubMenu); + } + else + { + delete pSubMenu; + } +} + + +void CCNotePad::slot_batchFind() +{ + if (m_batchFindWin.isNull()) + { + m_batchFindWin = new BatchFindReplace(this); + m_batchFindWin->setAttribute(Qt::WA_DeleteOnClose); + + BatchFindReplace* pWin = dynamic_cast(m_batchFindWin.data()); + pWin->setTabWidget(ui.editTabWidget); + + } + m_batchFindWin->show(); + +#ifdef uos + adjustWInPos(m_batchFindWin); +#endif + +} + #ifdef Q_OS_WIN void CCNotePad::checkAppFont() { @@ -1280,11 +1458,10 @@ void CCNotePad::slot_bookMarkAction() //动态加载书签的菜单项 void CCNotePad::slot_loadBookMarkMenu() { - static bool isInitBookMarkAct = false; - if (!isInitBookMarkAct) + if (!m_isInitBookMarkAct) { - isInitBookMarkAct = true; + m_isInitBookMarkAct = true; QAction* pAct = nullptr; pAct = ui.menuBook_Mark->addAction(tr("Set/Remove BookMark"), this, &CCNotePad::slot_bookMarkAction, QKeySequence("Ctrl+F2")); @@ -1327,6 +1504,18 @@ void CCNotePad::slot_markColorGroup(QAction *action) #define SCE_UNIVERSAL_FOUND_STYLE_START 20 +//修改标记样式的颜色 +void CCNotePad::changeMarkColor(int sytleId) +{ + if (sytleId < 5) + { + QPixmap colorBar(36, 36); + colorBar.fill((&StyleSet::s_global_style->mark_style_1)[sytleId].bgColor); + m_styleMarkActList.at(sytleId)->setIcon(colorBar); + } +} + + void CCNotePad::slot_loadMarkColor() { if (m_curColorIndex == -1) @@ -1339,7 +1528,7 @@ void CCNotePad::slot_loadMarkColor() connect(markColorGroup, &QActionGroup::triggered, this, &CCNotePad::slot_markColorGroup, Qt::QueuedConnection); int index = 1; - auto initColorBar = [this, markColorGroup,&index](QPixmap& colorBar) { + auto initColorBar = [this, markColorGroup,&index](QPixmap& colorBar)->QAction* { QAction* action = new QAction(ui.menuMark_Color); action->setIcon(colorBar); action->setText(tr("Color %1").arg(index)); @@ -1347,61 +1536,31 @@ void CCNotePad::slot_loadMarkColor() ++index; ui.menuMark_Color->addAction(action); markColorGroup->addAction(action); + return action; }; - colorBar.fill(QColor(0xffff00)); - initColorBar(colorBar); + m_styleMarkActList.clear(); - colorBar.fill(QColor(0x00ffff)); - initColorBar(colorBar); + colorBar.fill(StyleSet::s_global_style->mark_style_1.bgColor); + m_styleMarkActList.append(initColorBar(colorBar)); - colorBar.fill(QColor(0xff8000)); - initColorBar(colorBar); + colorBar.fill(StyleSet::s_global_style->mark_style_2.bgColor); + m_styleMarkActList.append(initColorBar(colorBar)); - colorBar.fill(QColor(0x8000ff)); - initColorBar(colorBar); + colorBar.fill(StyleSet::s_global_style->mark_style_3.bgColor); + m_styleMarkActList.append(initColorBar(colorBar)); - colorBar.fill(QColor(0x0080ff)); - initColorBar(colorBar); + colorBar.fill(StyleSet::s_global_style->mark_style_4.bgColor); + m_styleMarkActList.append(initColorBar(colorBar)); + + colorBar.fill(StyleSet::s_global_style->mark_style_5.bgColor); + m_styleMarkActList.append(initColorBar(colorBar)); } } void CCNotePad::syncCurSkinToMenu(int id) { - switch (id) - { - case DEFAULT_SE: - ui.actionDefaultStyle->setChecked(true); - break; - case LIGHT_SE: - ui.actionLightBlueStyle->setChecked(true); - break; - case THIN_BLUE_SE: - ui.actionThinBlue->setChecked(true); - break; - case THIN_YELLOW_SE: - ui.actionYellow->setChecked(true); - break; - case RICE_YELLOW_SE: - ui.actionRiceYellow->setChecked(true); - break; - case SILVER_SE: - ui.actionSilver->setChecked(true); - break; - case LAVENDER_SE: - ui.actionLavenderBlush->setChecked(true); - break; - case MISTYROSE_SE: - ui.actionMistyRose->setChecked(true); - break; - case BLACK_SE: - ui.actionDark->setChecked(true); - break; - default: - ui.actionDefaultStyle->setChecked(true); - break; - } s_curStyleId = id; } @@ -1750,29 +1909,14 @@ QString getRegularFilePath(QString& path) void CCNotePad::slot_showFileInExplorer() { - QString path, cmd; + QString path; QWidget* pw = ui.editTabWidget->currentWidget(); if (pw != nullptr) { path = pw->property(Edit_View_FilePath).toString(); } - -#ifdef _WIN32 - path = path.replace("/", "\\"); - cmd = QString("explorer.exe /select,%1").arg(path); -#endif -#ifdef uos - path = path.replace("\\", "/"); - cmd = QString("dde-file-manager %1").arg(path); -#endif -#if defined(Q_OS_MAC) - path = path.replace("\\", "/"); - cmd = QString("open -R %1").arg(path); -#endif - - QProcess process; - process.startDetached(cmd); + showFileInExplorer(path); } @@ -1802,11 +1946,11 @@ void CCNotePad::autoSetDocLexer(ScintillaEditView* pEdit) { QString filePath = pEdit->property(Edit_View_FilePath).toString(); - OpenAttr openType = (OpenAttr)pEdit->property(Open_Attr).toInt(); - if (OpenAttr::Text != openType) - { - return; - } + //OpenAttr openType = (OpenAttr)pEdit->property(Open_Attr).toInt(); + //if (OpenAttr::Text != openType && OpenAttr::BigTextReadOnly != openType) + //{ + // return; + //} LexerInfo lxdata = getLangLexerIdByFileExt(filePath); @@ -1844,15 +1988,14 @@ void CCNotePad::slot_tabCurrentChanged(int index) QWidget* pw = ui.editTabWidget->widget(index); if (pw != nullptr) { + QString filePath = getFilePathProperty(pw); //16进制的处理逻辑 int docType = getDocTypeProperty(pw); if (HEX_TYPE == docType) { - //setWindowTitle(pw->property(Edit_View_FilePath).toString()); - //m_wordwrap->setChecked(false); - //m_allWhite->setChecked(false); - QString filePath = getFilePathProperty(pw); + setWindowTitleMode(filePath, OpenAttr::HexReadOnly); + fileListSetCurItem(filePath); return; } else if ((TXT_TYPE == docType)||(BIG_TEXT_TYPE == docType)) @@ -1876,12 +2019,12 @@ void CCNotePad::slot_tabCurrentChanged(int index) if (TXT_TYPE == docType) { //setWindowTitle(pw->property(Edit_View_FilePath).toString()); - setWindowTitleMode(pw->property(Edit_View_FilePath).toString(), (OpenAttr)pw->property(Open_Attr).toInt()); + setWindowTitleMode(filePath, (OpenAttr)pw->property(Open_Attr).toInt()); } else if (BIG_TEXT_TYPE == docType) { //setWindowTitle(QString("%1 (%2)").arg(pw->property(Edit_View_FilePath).toString()).arg(tr("Big Text File ReadOnly"))); - setWindowTitleMode(pw->property(Edit_View_FilePath).toString(), OpenAttr::BigTextReadOnly); + setWindowTitleMode(filePath, OpenAttr::BigTextReadOnly); } syncCurDocEncodeToMenu(pw); @@ -1890,27 +2033,21 @@ void CCNotePad::slot_tabCurrentChanged(int index) ScintillaEditView* pEdit = dynamic_cast(pw); - //目前只用了0 1 两种换行模式。 + //目前只用了0 2 两种换行模式。 if (s_autoWarp != pEdit->wrapMode()) { - pEdit->setWrapMode((QsciScintilla::WrapMode)s_autoWarp); + pEdit->setWrapMode((s_autoWarp == 0 ? QsciScintilla::WrapNone: QsciScintilla::WrapCharacter)); } - - /*if (QsciScintilla::WsVisible == pEdit->whitespaceVisibility()) - { - m_allWhite->setChecked(true); + + fileListSetCurItem(filePath); } - else - { - m_allWhite->setChecked(false); - }*/ } } - } //快捷按钮的初始化 void CCNotePad::setShoctIcon(int iconSize) { +#if 0 auto setDark32Icon = [this]() { //黑色图标 @@ -1939,13 +2076,16 @@ void CCNotePad::setShoctIcon(int iconSize) m_preHexPage->setIcon(QIcon(PreHexIconDark32)); m_nextHexPage->setIcon(QIcon(NextHexIconDark32)); m_gotoHexPage->setIcon(QIcon(GotoHexIconDark32)); + m_fileCompare->setIcon(QIcon(FileCompareIconDark32)); + m_dirCompare->setIcon(QIcon(DirCompareIconDark32)); + m_binCompare->setIcon(QIcon(BinCmpIconDark32)); m_transcode->setIcon(QIcon(TransCodeIconDark32)); m_rename->setIcon(QIcon(RenameIconDark32)); }; if (iconSize < 48) { - if (iconSize == 36 && StyleSet::getCurrentSytleId() == BLACK_SE) + if (iconSize == 36 && StyleSet::getCurrentSytleId() == DEEP_BLACK) { setDark32Icon(); } @@ -1976,14 +2116,87 @@ void CCNotePad::setShoctIcon(int iconSize) m_preHexPage->setIcon(QIcon(PreHexIcon)); m_nextHexPage->setIcon(QIcon(NextHexIcon)); m_gotoHexPage->setIcon(QIcon(GotoHexIcon)); + m_fileCompare->setIcon(QIcon(FileCompareIcon)); + m_dirCompare->setIcon(QIcon(DirCompareIcon)); + m_binCompare->setIcon(QIcon(BinCmpIcon)); m_transcode->setIcon(QIcon(TransCodeIcon)); m_rename->setIcon(QIcon(RenameIcon)); } } else { - if (StyleSet::getCurrentSytleId() != BLACK_SE) + if (StyleSet::getCurrentSytleId() != DEEP_BLACK) { + m_newFile->setIcon(QIcon(NewFileIcon32)); + m_openFile->setIcon(QIcon(OpenFileIcon32)); + m_saveFile->setIcon(QIcon(NoNeedSaveBarIcon32)); + m_saveAllFile->setIcon(QIcon(NoNeedSaveAllBarIcon32)); + m_autoSaveAFile->setIcon(QIcon(AutoTimeSaveBarIcon32)); + m_closeFile->setIcon(QIcon(CloseFileIcon32)); + m_closeAllFile->setIcon(QIcon(CloseAllFileIcon32)); + m_cutFile->setIcon(QIcon(CutIcon32)); + m_copyFile->setIcon(QIcon(CopyFileIcon32)); + m_pasteFile->setIcon(QIcon(PasteIcon32)); + m_undo->setIcon(QIcon(UndoIcon32)); + m_redo->setIcon(QIcon(RedoIcon32)); + m_findText->setIcon(QIcon(FindIcon32)); + m_replaceText->setIcon(QIcon(ReplaceIcon32)); + m_markText->setIcon(QIcon(MarkIcon32)); + m_signText->setIcon(QIcon(SignIcon32)); + m_clearMark->setIcon(QIcon(ClearSignIcon32)); + m_zoomin->setIcon(QIcon(ZoominIcon32)); + m_zoomout->setIcon(QIcon(ZoomoutIcon32)); + m_wordwrap->setIcon(QIcon(CrlfIcon32)); + m_allWhite->setIcon(QIcon(WhiteIcon32)); + m_indentGuide->setIcon(QIcon(IndentIcon32)); + m_preHexPage->setIcon(QIcon(PreHexIcon32)); + m_nextHexPage->setIcon(QIcon(NextHexIcon32)); + m_gotoHexPage->setIcon(QIcon(GotoHexIcon32)); + m_fileCompare->setIcon(QIcon(FileCompareIcon32)); + m_dirCompare->setIcon(QIcon(DirCompareIcon32)); + m_binCompare->setIcon(QIcon(BinCmpIcon32)); + m_transcode->setIcon(QIcon(TransCodeIcon32)); + m_rename->setIcon(QIcon(RenameIcon32)); + } + else + { + setDark32Icon(); + } +} +#endif + + if (iconSize < 48) + { + m_newFile->setIcon(QIcon(NewFileIcon)); + m_openFile->setIcon(QIcon(OpenFileIcon)); + m_saveFile->setIcon(QIcon(NoNeedSaveBarIcon)); + m_saveAllFile->setIcon(QIcon(NoNeedSaveAllBarIcon)); + m_autoSaveAFile->setIcon(QIcon(AutoTimeSaveBarIcon)); + m_closeFile->setIcon(QIcon(CloseFileIcon)); + m_closeAllFile->setIcon(QIcon(CloseAllFileIcon)); + m_cutFile->setIcon(QIcon(CutIcon)); + m_copyFile->setIcon(QIcon(CopyFileIcon)); + m_pasteFile->setIcon(QIcon(PasteIcon)); + m_undo->setIcon(QIcon(UndoIcon)); + m_redo->setIcon(QIcon(RedoIcon)); + m_findText->setIcon(QIcon(FindIcon)); + m_replaceText->setIcon(QIcon(ReplaceIcon)); + m_markText->setIcon(QIcon(MarkIcon)); + m_signText->setIcon(QIcon(SignIcon)); + m_clearMark->setIcon(QIcon(ClearSignIcon)); + m_zoomin->setIcon(QIcon(ZoominIcon)); + m_zoomout->setIcon(QIcon(ZoomoutIcon)); + m_wordwrap->setIcon(QIcon(CrlfIcon)); + m_allWhite->setIcon(QIcon(WhiteIcon)); + m_indentGuide->setIcon(QIcon(IndentIcon)); + m_preHexPage->setIcon(QIcon(PreHexIcon)); + m_nextHexPage->setIcon(QIcon(NextHexIcon)); + m_gotoHexPage->setIcon(QIcon(GotoHexIcon)); + m_transcode->setIcon(QIcon(TransCodeIcon)); + m_rename->setIcon(QIcon(RenameIcon)); +} + else + { m_newFile->setIcon(QIcon(NewFileIcon32)); m_openFile->setIcon(QIcon(OpenFileIcon32)); m_saveFile->setIcon(QIcon(NoNeedSaveBarIcon32)); @@ -2012,11 +2225,6 @@ void CCNotePad::setShoctIcon(int iconSize) m_transcode->setIcon(QIcon(TransCodeIcon32)); m_rename->setIcon(QIcon(RenameIcon32)); } - else - { - setDark32Icon(); - } -} } void CCNotePad::initToolBar() @@ -2188,13 +2396,13 @@ void CCNotePad::initToolBar() m_wordwrap = new QToolButton(ui.mainToolBar); m_wordwrap->setCheckable(true); - m_wordwrap->setChecked((s_autoWarp == 1)); + m_wordwrap->setChecked((s_autoWarp != QsciScintilla::WrapNone)); connect(m_wordwrap, &QAbstractButton::toggled, this, &CCNotePad::slot_wordwrap); m_wordwrap->setFixedSize(ICON_SIZE, ICON_SIZE); m_wordwrap->setToolTip(tr("Word Wrap")); ui.mainToolBar->addWidget(m_wordwrap); - ui.actionWrap->setChecked((s_autoWarp == 1)); + ui.actionWrap->setChecked((s_autoWarp != QsciScintilla::WrapNone)); connect(ui.actionWrap, &QAction::toggled, m_wordwrap, [&](bool check) { //避免循环触发 @@ -2380,17 +2588,17 @@ void CCNotePad::initToolBar() m_pLexerActGroup->addAction(ui.actionTxt); m_pLexerActGroup->addAction(ui.actionUserDefine); - QActionGroup* skinStyleGroup = new QActionGroup(this); - skinStyleGroup->addAction(ui.actionDefaultStyle); - skinStyleGroup->addAction(ui.actionLightBlueStyle); - skinStyleGroup->addAction(ui.actionThinBlue); - skinStyleGroup->addAction(ui.actionYellow); - skinStyleGroup->addAction(ui.actionRiceYellow); - skinStyleGroup->addAction(ui.actionSilver); - skinStyleGroup->addAction(ui.actionLavenderBlush); - skinStyleGroup->addAction(ui.actionMistyRose); - skinStyleGroup->addAction(ui.actionDark); - connect(skinStyleGroup, &QActionGroup::triggered, this, &CCNotePad::slot_skinStyleGroup, Qt::QueuedConnection); + //QActionGroup* skinStyleGroup = new QActionGroup(this); + //skinStyleGroup->addAction(ui.actionDefaultStyle); + //skinStyleGroup->addAction(ui.actionLightBlueStyle); + //skinStyleGroup->addAction(ui.actionThinBlue); + //skinStyleGroup->addAction(ui.actionYellow); + //skinStyleGroup->addAction(ui.actionRiceYellow); + //skinStyleGroup->addAction(ui.actionSilver); + //skinStyleGroup->addAction(ui.actionLavenderBlush); + //skinStyleGroup->addAction(ui.actionMistyRose); + //skinStyleGroup->addAction(ui.actionDark); + //connect(skinStyleGroup, &QActionGroup::triggered, this, &CCNotePad::slot_skinStyleGroup, Qt::QueuedConnection); QActionGroup* langsGroup = new QActionGroup(this); langsGroup->addAction(ui.actionChinese); @@ -2413,37 +2621,48 @@ void CCNotePad::initToolBar() } -void CCNotePad::slot_skinStyleGroup(QAction* /*action*/) +//void CCNotePad::slot_skinStyleGroup(QAction* /*action*/) +//{ +// //切换图标 +// setShoctIcon(m_curIconSize); +// +// if (s_curStyleId != StyleSet::m_curStyleId) +// { +// //if (DEEP_BLACK == StyleSet::m_curStyleId) +// //{ +// // //如果不存在暗黑配置,则需要修正一次。后续如果存在了,则不需要再修正颜色 +// // if (!QtLangSet::isExistDarkLangSetings()) +// // { +// // QtLangSet::setAllLangFontFgColorToDarkStyle(); +// //} +// //} +// s_curStyleId = StyleSet::m_curStyleId; +// } +// +// for (int i = ui.editTabWidget->count() - 1; i >= 0; --i) +// { +// QWidget* pw = ui.editTabWidget->widget(i); +// ScintillaEditView *pEdit = dynamic_cast(pw); +// if (pEdit != nullptr) +// { +// pEdit->adjuctSkinStyle(); +// autoSetDocLexer(pEdit); +// } +// else +// { +// ScintillaHexEditView* pEdit = dynamic_cast(pw); +// if (pEdit != nullptr) +// { +// pEdit->adjuctSkinStyle(); +// } +// } +// } +//} + +void CCNotePad::setZoomLabelValue(int zoomValue) { - //切换图标 - setShoctIcon(m_curIconSize); - - if (s_curStyleId != StyleSet::m_curStyleId) - { - if (BLACK_SE == StyleSet::m_curStyleId) - { - //如果不存在暗黑配置,则需要修正一次。后续如果存在了,则不需要再修正颜色 - if (!QtLangSet::isExistDarkLangSetings()) - { - QtLangSet::setAllLangFontFgColorToDarkStyle(); + m_zoomLabel->setText(tr("Zoom: %1%").arg(zoomValue)); } - } - s_curStyleId = StyleSet::m_curStyleId; - } - - for (int i = ui.editTabWidget->count() - 1; i >= 0; --i) - { - QWidget* pw = ui.editTabWidget->widget(i); - ScintillaEditView *pEdit = dynamic_cast(pw); - if (pEdit != nullptr) - { - pEdit->adjuctSkinStyle(); - autoSetDocLexer(pEdit); - } - } - - -} void CCNotePad::slot_changeIconSize(QAction *action) { @@ -2488,8 +2707,7 @@ void CCNotePad::slot_changeIconSize(QAction *action) void CCNotePad::setTxtLexer(ScintillaEditView* pEdit) { - QsciLexerText* lexer = new QsciLexerText(); - lexer->setLexerTag("txt"); + QsciLexer* lexer = ScintillaEditView::createLexer(L_TXT, ""); pEdit->setLexer(lexer); } @@ -2688,7 +2906,7 @@ void CCNotePad::reloadEditFile(ScintillaEditView* pEidt) //设置为非脏,直接关闭,关闭后再打开 pEidt->setProperty(Edit_Text_Change, QVariant(false)); - slot_tabClose(ui.editTabWidget->currentIndex()); + tabClose(pEidt); openFile(filePath); } @@ -2696,18 +2914,32 @@ bool CCNotePad::checkRoladFile(ScintillaEditView* pEdit) { if (pEdit != nullptr && pEdit->property(Modify_Outside).toBool()) { + //防止该函数重入,导致时序错误 + if (m_isInReloadFile) + { + return false; + } + + m_isInReloadFile = true; + QString filePath = pEdit->property(Edit_View_FilePath).toString(); QApplication::beep(); if (QMessageBox::Yes == QMessageBox::question(this, tr("Reload"), tr("\"%1\" This file has been modified by another program. Do you want to reload it?").arg(filePath))) { + //reloadEditFile 里面会关闭和新增tab,触发一系列的currentChanged + disconnect(ui.editTabWidget, &QTabWidget::currentChanged, this, &CCNotePad::slot_tabCurrentChanged); reloadEditFile(pEdit); + connect(ui.editTabWidget, &QTabWidget::currentChanged, this, &CCNotePad::slot_tabCurrentChanged, Qt::UniqueConnection); } else { pEdit->setProperty(Modify_Outside, QVariant(false)); } + + m_isInReloadFile = false; + return true; } @@ -2759,7 +2991,7 @@ void CCNotePad::slot_editViewMofidyChange() int index = ui.editTabWidget->indexOf(pEditView); if (index != -1) { - if (StyleSet::getCurrentSytleId() != BLACK_SE) + if (StyleSet::getCurrentSytleId() != DEEP_BLACK) { ui.editTabWidget->setTabIcon(index, QIcon(TabNeedSave)); } @@ -2848,7 +3080,7 @@ void CCNotePad::tabClose(int index, bool isInQuit) { initTabNewOne(); } - + delFileListView(filePath); return; } else if (BIG_TEXT_TYPE == type) @@ -2861,6 +3093,7 @@ void CCNotePad::tabClose(int index, bool isInQuit) { initTabNewOne(); } + delFileListView(filePath); return; } @@ -2971,6 +3204,8 @@ void CCNotePad::tabClose(int index, bool isInQuit) updateCurTabSaveStatus(); + delFileListView(filePath); + if (!isInQuit) { initTabNewOne(); @@ -2983,6 +3218,19 @@ void CCNotePad::slot_tabClose(int index) tabClose(index); } +void CCNotePad::tabClose(QWidget* pEdit) +{ + for (int i = 0; i < ui.editTabWidget->count(); ++i) + { + if (pEdit == ui.editTabWidget->widget(i)) + { + tabClose(i); + break; + } + } + +} + //输入参数:名称和文件新建文件序号。一定是文本文件。contentPath:从这个路径加载文件内容,目前在恢复文件中使用。 ScintillaEditView* CCNotePad::newTxtFile(QString name, int index, QString contentPath) { @@ -3012,7 +3260,7 @@ ScintillaEditView* CCNotePad::newTxtFile(QString name, int index, QString conten connect(pEdit, &ScintillaEditView::cursorPositionChanged, this, &CCNotePad::slot_LineNumIndexChange, Qt::QueuedConnection); connect(pEdit, &ScintillaEditView::copyAvailable, this, &CCNotePad::slot_copyAvailable); - connect(pEdit, SIGNAL(SCN_ZOOM()), pEdit, SLOT(updateLineNumberWidth())); + connect(pEdit, SIGNAL(SCN_ZOOM()), this, SLOT(slot_zoomValueChange())); enableEditTextChangeSign(pEdit); @@ -3022,7 +3270,9 @@ ScintillaEditView* CCNotePad::newTxtFile(QString name, int index, QString conten QString label = name; - int curIndex = ui.editTabWidget->addTab(pEdit, QIcon((StyleSet::getCurrentSytleId() != BLACK_SE)? TabNoNeedSave:TabNoNeedSaveDark32), label); + disconnect(ui.editTabWidget, &QTabWidget::currentChanged, this, &CCNotePad::slot_tabCurrentChanged); + + int curIndex = ui.editTabWidget->addTab(pEdit, QIcon((StyleSet::getCurrentSytleId() != DEEP_BLACK)? TabNoNeedSave:TabNoNeedSaveDark32), label); QVariant editViewFilePath(label); pEdit->setProperty(Edit_View_FilePath, editViewFilePath); @@ -3061,10 +3311,12 @@ ScintillaEditView* CCNotePad::newTxtFile(QString name, int index, QString conten ui.editTabWidget->setCurrentIndex(curIndex); + connect(ui.editTabWidget, &QTabWidget::currentChanged, this, &CCNotePad::slot_tabCurrentChanged, Qt::UniqueConnection); + //设置自动转换和缩进参考线 - if (s_autoWarp == 1) + if (s_autoWarp != QsciScintilla::WrapNone) { - pEdit->setWrapMode(QsciScintilla::WrapWord); + pEdit->setWrapMode(QsciScintilla::WrapCharacter); } if (s_showblank == 1) @@ -3080,7 +3332,11 @@ ScintillaEditView* CCNotePad::newTxtFile(QString name, int index, QString conten autoSetDocLexer(pEdit); - ui.statusBar->showMessage(tr("New File Finished [Text Mode] Zoom %1%").arg(100 + 10 * s_zoomValue), 8000); + int zoomValue = 100 + 10 * s_zoomValue; + ui.statusBar->showMessage(tr("New File Finished [Text Mode] Zoom %1%").arg(zoomValue), 8000); + setZoomLabelValue(zoomValue); + + addFileListView(name, pEdit); return pEdit; } @@ -3164,12 +3420,14 @@ bool CCNotePad::openBigTextFile(QString filePath) TextFileMgr* txtFile = nullptr; - if (!FileManager::getInstance().loadFileData(filePath, txtFile)) + RC_LINE_FORM lineEnd(UNKNOWN_LINE); + + if (!FileManager::getInstance().loadFileData(filePath, txtFile, lineEnd)) { return false; } - ScintillaEditView* pEdit = FileManager::getInstance().newEmptyDocument(); + ScintillaEditView* pEdit = FileManager::getInstance().newEmptyDocument(true); pEdit->setReadOnly(true); pEdit->setNoteWidget(this); @@ -3179,9 +3437,16 @@ bool CCNotePad::openBigTextFile(QString filePath) showBigTextFile(pEdit, txtFile); - int curIndex = ui.editTabWidget->addTab(pEdit, QIcon((StyleSet::getCurrentSytleId() != BLACK_SE) ? TabNoNeedSave : TabNoNeedSaveDark32), getShortName(fileLabel)); + disconnect(ui.editTabWidget, &QTabWidget::currentChanged, this, &CCNotePad::slot_tabCurrentChanged); + int curIndex = ui.editTabWidget->addTab(pEdit, QIcon((StyleSet::getCurrentSytleId() != DEEP_BLACK) ? TabNoNeedSave : TabNoNeedSaveDark32), getShortName(fileLabel)); ui.editTabWidget->setCurrentIndex(curIndex); + connect(ui.editTabWidget, &QTabWidget::currentChanged, this, &CCNotePad::slot_tabCurrentChanged, Qt::UniqueConnection); + + + autoSetDocLexer(pEdit); + + pEdit->showBigTextLineAddr(txtFile->fileOffset - txtFile->contentRealSize); QVariant editViewFilePath(filePath); pEdit->setProperty(Edit_View_FilePath, editViewFilePath); @@ -3196,19 +3461,57 @@ bool CCNotePad::openBigTextFile(QString filePath) QVariant editTextChange(false); pEdit->setProperty(Edit_Text_Change, editTextChange); + setLineEndBarLabel(lineEnd); + syncCurDocEncodeToMenu(pEdit); setFileOpenAttrProperty(pEdit, OpenAttr::BigTextReadOnly); setWindowTitleMode(filePath, OpenAttr::BigTextReadOnly); + + //设置自动转换和缩进参考线 + if (s_autoWarp != QsciScintilla::WrapNone) + { + pEdit->setWrapMode(QsciScintilla::WrapCharacter); + } + if (s_showblank == 1) + { + pEdit->setWhitespaceVisibility(QsciScintilla::WsVisible); + pEdit->setEolVisibility(true); + } + + if (s_indent == 1) + { + pEdit->setIndentGuide(true); + } + + if (s_zoomValue != 0) + { + pEdit->zoomTo(s_zoomValue); + } + + addFileListView(filePath, pEdit); + return true; } +void CCNotePad::showChangePageTips(QWidget* pEdit) +{ + int type = getDocTypeProperty(pEdit); + + if (BIG_TEXT_TYPE == type || HEX_TYPE == type) + { + ui.statusBar->showMessage(tr("Use < (Pre) or > (Next) and Goto Buttons to Change Page Num ."), 10000); + } +} + void CCNotePad::setWindowTitleMode(QString filePath, OpenAttr attr) { QString title = QString("%1 [%2]").arg(filePath).arg(OpenAttrToString(attr)); setWindowTitle(title); } +const quint32 MAX_TRY_OPEN_FILE_SIZE = 1024 * 1024 * 1000; + //打开普通文本文件。 bool CCNotePad::openTextFile(QString filePath, bool isCheckHex, CODE_ID code) { @@ -3229,8 +3532,39 @@ bool CCNotePad::openTextFile(QString filePath, bool isCheckHex, CODE_ID code) if (fi.size() > ScintillaEditView::s_bigTextSize*1024*1024) { + //文件如果小于1G,询问用户如何打开。如果大于1G,无条件分块加载 + if (fi.size() < MAX_TRY_OPEN_FILE_SIZE) + { + BigFileMessage askMsgBox(this); + askMsgBox.setTip(tr("File %1 \nFile Size %2 > %3M, How to Open it ?").arg(filePath).arg(fi.size()).arg(ScintillaEditView::s_bigTextSize)); + int openMode = askMsgBox.exec(); + + //放弃打开 + if (openMode == -1) + { + return false; + } + else if (openMode == 0) + { + //正常普通文本打开,不做什么,继续往下走 + } + else if (openMode == 1) + { + //大文本只读打开 return openBigTextFile(filePath); } + else + { + //二进制打开 + return openHexFile(filePath); + } + } + else + { + //大文本只读打开 + return openBigTextFile(filePath); + } + } if (QFile::exists(swapfile)) { @@ -3301,13 +3635,16 @@ bool CCNotePad::openTextFile(QString filePath, bool isCheckHex, CODE_ID code) saveFile(filePath, pEdit, false); } - int curIndex = ui.editTabWidget->addTab(pEdit, QIcon((StyleSet::getCurrentSytleId() != BLACK_SE) ? TabNoNeedSave : TabNoNeedSaveDark32), getShortName(fileLabel)); - ui.editTabWidget->setCurrentIndex(curIndex); + //防止addTab触发currentChanged信号,应发不必要的连锁反应 + disconnect(ui.editTabWidget, &QTabWidget::currentChanged, this, &CCNotePad::slot_tabCurrentChanged); + int curIndex = ui.editTabWidget->addTab(pEdit, QIcon((StyleSet::getCurrentSytleId() != DEEP_BLACK) ? TabNoNeedSave : TabNoNeedSaveDark32), getShortName(fileLabel)); + ui.editTabWidget->setCurrentWidget(pEdit); + connect(ui.editTabWidget, &QTabWidget::currentChanged, this, &CCNotePad::slot_tabCurrentChanged, Qt::UniqueConnection); connect(pEdit, &ScintillaEditView::cursorPositionChanged, this, &CCNotePad::slot_LineNumIndexChange, Qt::QueuedConnection); enableEditTextChangeSign(pEdit); connect(pEdit, &ScintillaEditView::copyAvailable, this, &CCNotePad::slot_copyAvailable); - connect(pEdit, SIGNAL(SCN_ZOOM()), pEdit, SLOT(updateLineNumberWidth())); + connect(pEdit, SIGNAL(SCN_ZOOM()), this, SLOT(slot_zoomValueChange())); //监控文件 addWatchFilePath(filePath); @@ -3340,9 +3677,9 @@ bool CCNotePad::openTextFile(QString filePath, bool isCheckHex, CODE_ID code) syncCurDocLexerToMenu(pEdit); //设置自动转换和缩进参考线 - if (s_autoWarp == 1) + if (s_autoWarp != QsciScintilla::WrapNone) { - pEdit->setWrapMode(QsciScintilla::WrapWord); + pEdit->setWrapMode(QsciScintilla::WrapCharacter); } if (s_showblank == 1) { @@ -3364,7 +3701,9 @@ bool CCNotePad::openTextFile(QString filePath, bool isCheckHex, CODE_ID code) { setFileOpenAttrProperty(pEdit, OpenAttr::Text); setWindowTitleMode(filePath, OpenAttr::Text); - ui.statusBar->showMessage(tr("File %1 Open Finished [Text Mode] Zoom %2%").arg(filePath).arg(100+10* s_zoomValue),8000); + int zoomValue = 100 + 10 * s_zoomValue; + ui.statusBar->showMessage(tr("File %1 Open Finished [Text Mode] Zoom %2%").arg(filePath).arg(zoomValue),8000); + setZoomLabelValue(zoomValue); } else { @@ -3377,7 +3716,7 @@ bool CCNotePad::openTextFile(QString filePath, bool isCheckHex, CODE_ID code) { autoSetDocLexer(pEdit); } - + addFileListView(filePath, pEdit); return true; } @@ -3515,9 +3854,11 @@ bool CCNotePad::openHexFile(QString filePath) showHexFile(pEdit,hexFile); - int curIndex = ui.editTabWidget->addTab(pEdit, QIcon((StyleSet::getCurrentSytleId() != BLACK_SE) ? TabNoNeedSave : TabNoNeedSaveDark32), getShortName(fileLabel)); + disconnect(ui.editTabWidget, &QTabWidget::currentChanged, this, &CCNotePad::slot_tabCurrentChanged); + int curIndex = ui.editTabWidget->addTab(pEdit, QIcon((StyleSet::getCurrentSytleId() != DEEP_BLACK) ? TabNoNeedSave : TabNoNeedSaveDark32), getShortName(fileLabel)); ui.editTabWidget->setCurrentIndex(curIndex); + connect(ui.editTabWidget, &QTabWidget::currentChanged, this, &CCNotePad::slot_tabCurrentChanged, Qt::UniqueConnection); QVariant editViewFilePath(filePath); pEdit->setProperty(Edit_View_FilePath, editViewFilePath); @@ -3538,9 +3879,139 @@ bool CCNotePad::openHexFile(QString filePath) ui.statusBar->showMessage(tr("File %1 Open Finished [Hex ReayOnly Mode]").arg(filePath),8000); + addFileListView(filePath, pEdit); + return true; } +void CCNotePad::slot_fileListView(bool check) +{ + if (check) + { + initFileListDockWin(); + syncFileTabToListView(); +} + else + { + if (!m_dockFileListWin.isNull()) + { + m_dockFileListWin->close(); + } + } +} + + +void CCNotePad::addFileListView(QString file, QWidget* pw) +{ + if (!m_dockFileListWin.isNull()) + { + m_fileListView->addFileItem(file, pw); + } +} +void CCNotePad::delFileListView(QString file) +{ + if (!m_dockFileListWin.isNull()) + { + m_fileListView->delFileItem(file); + } +} + +void CCNotePad::syncFileTabToListView() +{ + if (m_dockFileListWin.isNull()) + { + return; + } + + for (int i = 0; i < ui.editTabWidget->count(); ++i) + { + QWidget* pw = ui.editTabWidget->widget(i); + QString filePath = getFilePathProperty(pw); + m_fileListView->addFileItem(filePath,pw); + } +} + +void CCNotePad::fileListSetCurItem(QString filePath) +{ + if (!m_dockFileListWin.isNull()) + { + m_fileListView->setCurItem(filePath); + } +} + +//双击文件列表,定位到对应的文件 +void CCNotePad::slot_fileListItemDoubleClick(QListWidgetItem* item) +{ + if (!m_dockFileListWin.isNull()) + { + QWidget *pWid = m_fileListView->getWidgetByFilePath(item->text()); + if (pWid != nullptr) + { + ui.editTabWidget->setCurrentWidget(pWid); + } + } +} + +//在文件列表类中使用,关闭pEdit所在的编辑器 +bool CCNotePad::closeFileByEditWidget(QWidget* pEdit) +{ + int index = ui.editTabWidget->indexOf(pEdit); + if (index != -1) + { + slot_tabClose(index); + return true; + } + return false; +} + +void CCNotePad::initFileListDockWin() +{ + //停靠窗口1 + if (m_dockFileListWin.isNull()) + { + m_dockFileListWin = new QDockWidget(tr("File List"), this); + connect(m_dockFileListWin, &QDockWidget::dockLocationChanged, this, [](Qt::DockWidgetArea area) { + NddSetting::updataKeyValueFromNumSets(FILELISTPOS, area); + }); + + connect(m_dockFileListWin, &QObject::destroyed, this, [this] { + if (ui.actionFileListView->isChecked()) + { + ui.actionFileListView->setChecked(false); + } + }); + m_dockFileListWin->setAttribute(Qt::WA_DeleteOnClose); + m_dockFileListWin->layout()->setMargin(0); + m_dockFileListWin->layout()->setSpacing(0); + + //暂时不提供关闭,因为关闭后需要同步菜单的check状态 + + m_dockFileListWin->setFeatures(QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable); + m_dockFileListWin->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + + m_fileListView = new FileListView(m_dockFileListWin); + m_fileListView->setNotepadWin(this); + + connect(m_fileListView, &FileListView::itemDoubleClicked, this, &CCNotePad::slot_fileListItemDoubleClick); + + m_dockFileListWin->setWidget(m_fileListView); + + int lastArea = NddSetting::getKeyValueFromNumSets(FILELISTPOS); + if (lastArea == 0) + { + lastArea = Qt::LeftDockWidgetArea; + } + + addDockWidget((Qt::DockWidgetArea)lastArea, m_dockFileListWin); + + if (!ui.actionFileListView->isChecked()) + { + ui.actionFileListView->setChecked(true); + } + } + m_dockFileListWin->show(); +} + static QString fileSuffix(const QString& filePath) { QFileInfo fi(filePath); @@ -3583,27 +4054,7 @@ bool CCNotePad::openFile(QString filePath) //非已知的后缀文件,暂时无条件以二进制打开 return openTextFile(filePath); - -#if 0 - //如果不支持该文件ext,则以二进制形式打开 - if (DocTypeListView::isSupportExt(CompareDirs::fileSuffix(filePath))) - { - return openTextFile(filePath); } - else - { - static QMimeDatabase db; - QMimeType mime = db.mimeTypeForFile(fi); - if (mime.name().startsWith("text")) { - return openTextFile(filePath); - } - - ui.statusBar->showMessage(tr("file %1 may be a hex file , try open with text file.").arg(filePath), 10000); - - return openTextFile(filePath); - } -#endif -} void CCNotePad::slot_slectionChanged() { @@ -3650,9 +4101,10 @@ bool CCNotePad::saveFile(QString fileName, ScintillaEditView* pEdit, bool isBak if (srcfile.exists()) { + //linux也不是拥有者,可写权限就行 QFlags power = QFile::permissions(fileName); - if (!power.testFlag(QFile::WriteOwner)) + if (!power.testFlag(QFile::WriteUser)) { //文件不能写 QApplication::beep(); @@ -3669,7 +4121,7 @@ bool CCNotePad::saveFile(QString fileName, ScintillaEditView* pEdit, bool isBak isNewFile = true; } - auto saveWork = [this, &pEdit,isStatic](QFile& file, QString &fileName)->bool{ + auto saveWork = [this, &pEdit,isStatic](QFile& file, QString &fileName, bool isSwapFile=false)->bool{ if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate)) { @@ -3686,8 +4138,17 @@ bool CCNotePad::saveFile(QString fileName, ScintillaEditView* pEdit, bool isBak return false; } #endif + if (isSwapFile) + { + //如果是交换文件写失败,询问是否继续直接写文件 + return (QMessageBox::Yes == QMessageBox::question(this, tr("Error"), tr("Save Swap File %1 failed. Write the target file directly ?").arg(fileName))); + + } + else + { QMessageBox::warning(this, tr("Error"), tr("Save File %1 failed. You may not have write privileges \nPlease save as a new file!").arg(fileName)); } + } return false; } @@ -3755,7 +4216,7 @@ bool CCNotePad::saveFile(QString fileName, ScintillaEditView* pEdit, bool isBak QFile swapfile(swapFile); //老文件则先写入交换文件,避免断电后破坏文件不能恢复 //再写入原本文件 - bool success = saveWork(swapfile, fileName); + bool success = saveWork(swapfile, fileName, true); if (success) { success = saveWork(srcfile, fileName); @@ -3906,7 +4367,7 @@ void CCNotePad::slot_actionSaveFile_toggle(bool /*checked*/) } //一旦保存后,设置tab为不需要保存状态 - ui.editTabWidget->setTabIcon(index, QIcon((StyleSet::getCurrentSytleId() != BLACK_SE) ? TabNoNeedSave : TabNoNeedSaveDark32)); + ui.editTabWidget->setTabIcon(index, QIcon((StyleSet::getCurrentSytleId() != DEEP_BLACK) ? TabNoNeedSave : TabNoNeedSaveDark32)); //m_saveFile->setIcon(QIcon(NoNeedSaveBarIcon)); m_saveFile->setEnabled(false); @@ -4094,7 +4555,7 @@ void CCNotePad::slot_actionSaveAsFile_toggle(bool /*checked*/) //保持完毕后,设置tab为蓝色,显示为不需要保持状态 - ui.editTabWidget->setTabIcon(index, QIcon((StyleSet::getCurrentSytleId() != BLACK_SE) ? TabNoNeedSave : TabNoNeedSaveDark32)); + ui.editTabWidget->setTabIcon(index, QIcon((StyleSet::getCurrentSytleId() != DEEP_BLACK) ? TabNoNeedSave : TabNoNeedSaveDark32)); //m_saveFile->setIcon(QIcon(NoNeedSaveBarIcon)); m_saveFile->setEnabled(false); @@ -4542,6 +5003,9 @@ void CCNotePad::closeEvent(QCloseEvent * event) { if (!m_pFindWin.isNull()) { + QByteArray curGeo = m_pFindWin->saveGeometry(); + NddSetting::updataKeyByteArrayValue(FINDWINSIZE, curGeo); + m_pFindWin.data()->close(); } @@ -4550,6 +5014,22 @@ void CCNotePad::closeEvent(QCloseEvent * event) m_pHexGotoWin.data()->close(); } + if (!m_columnEditWin.isNull()) + { + m_columnEditWin.data()->close(); + } + + + //关闭的时候,filelistwin还存在 + if (!m_dockFileListWin.isNull()) + { + NddSetting::updataKeyValueFromNumSets(FILELISTSHOW, 1); + m_dockFileListWin.data()->close(); + } + else + { + NddSetting::updataKeyValueFromNumSets(FILELISTSHOW, 0); + } #ifdef Q_OS_WIN if ((s_restoreLastFile==1) && m_isMainWindows && !s_isAdminAuth) @@ -4725,6 +5205,61 @@ void CCNotePad::slot_redo() void CCNotePad::slot_zoomin() { + ++s_zoomValue; + + if (s_zoomValue < -10) + s_zoomValue = -10; + else if (s_zoomValue > 20) + s_zoomValue = 20; + + zoomto(s_zoomValue); +} + +//ctrl+鼠标放大缩小zoom,由pedit发送的消息 +//任何一个编辑框修改,其余的编辑框也需要同步修改 +void CCNotePad::slot_zoomValueChange() + { + ScintillaEditView* pSrcEdit = dynamic_cast(sender()); + if (pSrcEdit != nullptr) + { + pSrcEdit->updateLineNumberWidth(); + + int curZoomValue = pSrcEdit->execute(SCI_GETZOOM); + + if (s_zoomValue != curZoomValue) + { + s_zoomValue = curZoomValue; + NddSetting::updataKeyValueFromNumSets(ZOOMVALUE, s_zoomValue); + int zoomValue = 100 + 10 * curZoomValue; + ui.statusBar->showMessage(tr("Current Zoom Value is %1%").arg(zoomValue)); + setZoomLabelValue(zoomValue); + } + + //修改其余的pedit + for (int i = ui.editTabWidget->count() - 1; i >= 0; --i) + { + QWidget* pw = ui.editTabWidget->widget(i); + ScintillaEditView* pEdit = dynamic_cast(pw); + + if ((pEdit != nullptr) && (pEdit != pSrcEdit)) + { + //zoomTo 会触发SCN_ZOOM,而zoomTo会触发slot_zoomValueChange,避免循环触发 + disconnect(pEdit, SIGNAL(SCN_ZOOM()), this, SLOT(slot_zoomValueChange())); + pEdit->zoomTo(s_zoomValue); + pEdit->updateLineNumberWidth(); + connect(pEdit, SIGNAL(SCN_ZOOM()), this, SLOT(slot_zoomValueChange())); +} + } +} +} + +void CCNotePad::zoomto(int zoomValue) +{ + NddSetting::updataKeyValueFromNumSets(ZOOMVALUE, zoomValue); + int value = 100 + 10 * zoomValue; + ui.statusBar->showMessage(tr("Current Zoom Value is %1%").arg(value)); + setZoomLabelValue(value); + for (int i = ui.editTabWidget->count() - 1; i >= 0; --i) { @@ -4733,43 +5268,25 @@ void CCNotePad::slot_zoomin() if (pEdit != nullptr) { - pEdit->zoomIn(); - - int curZoomValue = pEdit->execute(SCI_GETZOOM); - - if (i == 0) - { - s_zoomValue = curZoomValue; - NddSetting::updataKeyValueFromNumSets(ZOOMVALUE, s_zoomValue); - ui.statusBar->showMessage(tr("Current Zoom Value is %1%").arg(100 + 10 * curZoomValue)); + //zoomTo 会触发SCN_ZOOM,而zoomTo会触发slot_zoomValueChange,避免循环触发 + disconnect(pEdit, SIGNAL(SCN_ZOOM()), this, SLOT(slot_zoomValueChange())); + pEdit->zoomTo(zoomValue); + pEdit->updateLineNumberWidth(); + connect(pEdit, SIGNAL(SCN_ZOOM()), this, SLOT(slot_zoomValueChange())); } } - } -} void CCNotePad::slot_zoomout() { - for (int i = ui.editTabWidget->count() - 1; i >= 0; --i) - { - QWidget* pw = ui.editTabWidget->widget(i); - ScintillaEditView* pEdit = dynamic_cast(pw); + --s_zoomValue; - if (pEdit != nullptr) - { - pEdit->zoomOut(); + if (s_zoomValue < -10) + s_zoomValue = -10; + else if (s_zoomValue > 20) + s_zoomValue = 20; - int curZoomValue = pEdit->execute(SCI_GETZOOM); - - if (i == 0) - { - s_zoomValue = curZoomValue; - NddSetting::updataKeyValueFromNumSets(ZOOMVALUE, s_zoomValue); - ui.statusBar->showMessage(tr("Current Zoom Value is %1%").arg(100 + 10 * curZoomValue)); - } -} - - } + zoomto(s_zoomValue); } //只切换了当前文档。可能会耗时,所以不全部换行。在文档切换的时候,需要检查下当前文档的自动换行状态。 @@ -4789,7 +5306,7 @@ void CCNotePad::slot_wordwrap(bool checked) { if (checked) { - pEdit->setWrapMode(QsciScintilla::WrapWord); + pEdit->setWrapMode(QsciScintilla::WrapCharacter); } else { @@ -4797,7 +5314,7 @@ void CCNotePad::slot_wordwrap(bool checked) } } - s_autoWarp = (checked) ? 1 : 0; + s_autoWarp = (checked) ? QsciScintilla::WrapCharacter : QsciScintilla::WrapNone; NddSetting::updataKeyValueFromNumSets(AUTOWARP_KEY, s_autoWarp); } @@ -4911,6 +5428,33 @@ void CCNotePad::slot_find() pFind->setCurrentTab(FIND_TAB); } +//在后台查找关键字 +int CCNotePad::findAtBack(QString keyword) +{ + initFindWindow(); + FindWin* pFind = dynamic_cast(m_pFindWin.data()); + return pFind->findAtBack(keyword); + +} +//在后台替换关键字 + +//在后台替换关键字 +int CCNotePad::replaceAtBack(QStringList& keyword, QStringList& replace) +{ + initFindWindow(); + FindWin* pFind = dynamic_cast(m_pFindWin.data()); + return pFind->replaceAtBack(keyword, replace); +} + +//在后台高亮关键字 +int CCNotePad::markAtBack(QString keyword) +{ + initFindWindow(); + FindWin* pFind = dynamic_cast(m_pFindWin.data()); + return pFind->markAllWord(keyword); +} + + void CCNotePad::initFindWindow() { FindWin* pFind = nullptr; @@ -4922,6 +5466,13 @@ void CCNotePad::initFindWindow() m_pFindWin = new FindWin(this); connect(m_pFindWin,&QObject::destroyed,this,&CCNotePad::slot_saveSearchHistory); + QByteArray lastGeo = NddSetting::getKeyByteArrayValue(FINDWINSIZE); + + if (!lastGeo.isEmpty()) + { + m_pFindWin->restoreGeometry(lastGeo); + } + pFind = dynamic_cast(m_pFindWin.data()); if (s_findHistroy.isEmpty()) @@ -5220,6 +5771,7 @@ void CCNotePad::initFindResultDockWin() m_dockSelectTreeWin = new QDockWidget(tr("Find result"), this); connect(m_dockSelectTreeWin, &QDockWidget::dockLocationChanged, this, &CCNotePad::slot_findResultPosChangeed); + m_dockSelectTreeWin->layout()->setMargin(0); m_dockSelectTreeWin->layout()->setSpacing(0); @@ -5754,6 +6306,7 @@ void CCNotePad::slot_preHexPage() { ScintillaEditView* pEdit = dynamic_cast(pw); showBigTextFile(pEdit, fileMgr); + pEdit->showBigTextLineAddr(fileMgr->fileOffset - fileMgr->contentRealSize); } } } @@ -5800,6 +6353,7 @@ void CCNotePad::slot_nextHexPage() { ScintillaEditView* pEdit = dynamic_cast(pw); showBigTextFile(pEdit, fileMgr); + pEdit->showBigTextLineAddr(fileMgr->fileOffset - fileMgr->contentRealSize); } else if (1 == ret) { @@ -5892,6 +6446,7 @@ void CCNotePad::slot_hexGotoFile(qint64 addr) { ScintillaEditView* pEdit = dynamic_cast(pw); showBigTextFile(pEdit, fileMgr); + pEdit->showBigTextLineAddr(fileMgr->fileOffset - fileMgr->contentRealSize); } else if (-2 == ret) { @@ -6047,11 +6602,26 @@ bool CCNotePad::nativeEvent(const QByteArray & eventType, void * message, long * ui.statusBar->showMessage(tr("file %1 already open at tab %2").arg(openFilePath).arg(retIndex)); ui.editTabWidget->setCurrentIndex(retIndex); } - //窗口如果最小化,则在任务栏下面闪动 QApplication::alert(this); - activateWindow(); + //发现在release模式下,必须要先最小再最大,窗口才能跑到最前面。而调试时则没有该现象。可能是哪里有个问题。 + if (!this->isMinimized()) + { + this->showMinimized(); + } + + if (this->isMaximized()) + { + this->showMaximized(); + } + else + { + this->showNormal(); + } + + + this->activateWindow(); *result = 1; return true; } @@ -6238,65 +6808,6 @@ void CCNotePad::slot_registerCmd(int cmd, int code) } } - - -void CCNotePad::slot_toLightBlueStyle() -{ - StyleSet::setLightStyle(); - - //皮肤id - NddSetting::updataKeyValueFromNumSets(SKIN_KEY,1); -} - -void CCNotePad::slot_toDefaultStyle() -{ - StyleSet::setDefaultStyle(); - NddSetting::updataKeyValueFromNumSets(SKIN_KEY, 0); -} - -void CCNotePad::slot_toThinBlueStyle() -{ - StyleSet::setThinBlueStyle(); - NddSetting::updataKeyValueFromNumSets(SKIN_KEY, 2); -} - -void CCNotePad::slot_toRiceYellow() -{ - StyleSet::setRiceYellowStyle(); - NddSetting::updataKeyValueFromNumSets(SKIN_KEY, 4); -} - -void CCNotePad::slot_toYellow() -{ - StyleSet::setThinYellowStyle(); - NddSetting::updataKeyValueFromNumSets(SKIN_KEY, 3); -} - -void CCNotePad::slot_toSilverStyle() -{ - StyleSet::setSilverStyle(); - NddSetting::updataKeyValueFromNumSets(SKIN_KEY, 5); -} - -void CCNotePad::slot_toLavenderBlush() -{ - StyleSet::setLavenderBlushStyle(); - NddSetting::updataKeyValueFromNumSets(SKIN_KEY, 6); -} - -void CCNotePad::slot_toMistyRose() -{ - StyleSet::setMistyRoseStyle(); - NddSetting::updataKeyValueFromNumSets(SKIN_KEY, 7); -} - -void CCNotePad::slot_toDarkStyle() -{ - StyleSet::setBlackStyle(); - NddSetting::updataKeyValueFromNumSets(SKIN_KEY, 8); -} - - //获取注册码 void CCNotePad::slot_register() { @@ -6516,13 +7027,15 @@ bool CCNotePad::restoreDirtyExistFile(QString& filePath, QString& tempFilePath) } } - int curIndex = ui.editTabWidget->addTab(pEdit, QIcon((StyleSet::getCurrentSytleId() != BLACK_SE) ? TabNoNeedSave : TabNoNeedSaveDark32), getShortName(fileLabel)); + disconnect(ui.editTabWidget, &QTabWidget::currentChanged, this, &CCNotePad::slot_tabCurrentChanged); + int curIndex = ui.editTabWidget->addTab(pEdit, QIcon((StyleSet::getCurrentSytleId() != DEEP_BLACK) ? TabNoNeedSave : TabNoNeedSaveDark32), getShortName(fileLabel)); ui.editTabWidget->setCurrentIndex(curIndex); + connect(ui.editTabWidget, &QTabWidget::currentChanged, this, &CCNotePad::slot_tabCurrentChanged, Qt::UniqueConnection); connect(pEdit, &ScintillaEditView::cursorPositionChanged, this, &CCNotePad::slot_LineNumIndexChange, Qt::QueuedConnection); enableEditTextChangeSign(pEdit); connect(pEdit, &ScintillaEditView::copyAvailable, this, &CCNotePad::slot_copyAvailable); - connect(pEdit, SIGNAL(SCN_ZOOM()), pEdit, SLOT(updateLineNumberWidth())); + connect(pEdit, SIGNAL(SCN_ZOOM()), this, SLOT(slot_zoomValueChange())); //监控文件 addWatchFilePath(filePath); @@ -6553,9 +7066,9 @@ bool CCNotePad::restoreDirtyExistFile(QString& filePath, QString& tempFilePath) syncCurDocLexerToMenu(pEdit); //设置自动转换和缩进参考线 - if (s_autoWarp == 1) + if (s_autoWarp != QsciScintilla::WrapNone) { - pEdit->setWrapMode(QsciScintilla::WrapWord); + pEdit->setWrapMode(QsciScintilla::WrapCharacter); } if (s_showblank == 1) @@ -6717,13 +7230,17 @@ void CCNotePad::slot_removeHeadEndBlank() void CCNotePad::slot_columnBlockEdit() { - ColumnEdit* pWin = new ColumnEdit(); - pWin->setAttribute(Qt::WA_DeleteOnClose); + if (m_columnEditWin.isNull()) + { + m_columnEditWin = new ColumnEdit(); + m_columnEditWin->setAttribute(Qt::WA_DeleteOnClose); + ColumnEdit* pWin = dynamic_cast(m_columnEditWin.data()); pWin->setTabWidget(ui.editTabWidget); - pWin->show(); - registerEscKeyShort(pWin); + } + m_columnEditWin->show(); + registerEscKeyShort(m_columnEditWin); #ifdef uos - adjustWInPos(pWin); + adjustWInPos(m_columnEditWin); #endif } @@ -7416,3 +7933,84 @@ void CCNotePad::slot_clearHistoryOpenList() m_receneOpenFileList.clear(); } + +void CCNotePad::slot_showToolBar(bool check) +{ + ui.mainToolBar->setVisible(check); + + NddSetting::updataKeyValueFromNumSets(TOOLBARSHOW, check?1:0); +} + +void CCNotePad::slot_showWebAddr(bool check) +{ + CCNotePad::s_hightWebAddr = check ? 1 : 0; + + NddSetting::updataKeyValueFromNumSets(SHOWWEBADDR, s_hightWebAddr); +} + +//更新当前主题的样式 +void CCNotePad::updateThemes() +{ + for (int i = ui.editTabWidget->count() - 1; i >= 0; --i) + { + QWidget* pw = ui.editTabWidget->widget(i); + + int docType = getDocTypeProperty(pw); + + if (docType != HEX_TYPE) + { + ScintillaEditView* pEdit = dynamic_cast(pw); + if (pEdit != nullptr) + { + pEdit->updateThemes(); + } + } + else + { + ScintillaHexEditView* pEdit = dynamic_cast(pw); + if (pEdit != nullptr) + { + pEdit->updateThemes(); + } + } + } +} + +void CCNotePad::setGlobalFgColor(int style) +{ + for (int i = ui.editTabWidget->count() - 1; i >= 0; --i) + { + QWidget* pw = ui.editTabWidget->widget(i); + ScintillaEditView* pEdit = dynamic_cast(pw); + if (pEdit != nullptr) + { + pEdit->setGlobalFgColor(style); + } + } +} + +void CCNotePad::setGlobalBgColor(int style) +{ + for (int i = ui.editTabWidget->count() - 1; i >= 0; --i) + { + QWidget* pw = ui.editTabWidget->widget(i); + ScintillaEditView* pEdit = dynamic_cast(pw); + if (pEdit != nullptr) + { + pEdit->setGlobalBgColor(style); + } + } +} + +void CCNotePad::setGlobalFont(int style) +{ + for (int i = ui.editTabWidget->count() - 1; i >= 0; --i) + { + QWidget* pw = ui.editTabWidget->widget(i); + ScintillaEditView* pEdit = dynamic_cast(pw); + if (pEdit != nullptr) + { + pEdit->setGlobalFont(style); + } + } +} diff --git a/src/cceditor/ccnotepad.h b/src/cceditor/ccnotepad.h index 7a7c0cc..62e640a 100755 --- a/src/cceditor/ccnotepad.h +++ b/src/cceditor/ccnotepad.h @@ -13,6 +13,7 @@ #include #include #include +#include #include "rcglobal.h" #include "ui_ccnotepad.h" @@ -20,6 +21,7 @@ #include "extlexermanager.h" #include "scintillaeditview.h" #include "findwin.h" +#include "pluginGl.h" //class ScintillaEditView; @@ -32,15 +34,6 @@ class CompareWin; struct HexFileMgr; struct TextFileMgr; -#define uos 1 - -#ifdef Q_OS_WIN -#undef uos -#endif - -#ifdef Q_OS_MAC -#undef uos -#endif enum OpenAttr { Text = 1, @@ -69,7 +62,7 @@ enum LINE_SORT_TYPE { //打开模式。1 文本 2 二进制 3 大文本只读 4 文本只读 //const char* Open_Attr = "openid"; - +class FileListView; class CCNotePad : public QMainWindow { @@ -127,8 +120,18 @@ public: void getCurUseLexerTags(QVector& tag); void clearHighlightWord(QString signWord, ScintillaEditView* pEdit = nullptr); + bool closeFileByEditWidget(QWidget* pEdit); + void showChangePageTips(QWidget* pEdit); + int markAtBack(QString keyword); + int findAtBack(QString keyword); + int replaceAtBack(QStringList& keyword, QStringList& replace); + void updateThemes(); + void setGlobalFgColor(int style); + void setGlobalBgColor(int style); + void setGlobalFont(int style); + void changeMarkColor(int sytleId); signals: void signSendRegisterKey(QString key); void signRegisterReplay(int code); @@ -146,6 +149,7 @@ public slots: void slot_actionCloseLeftAll(); void slot_actionCloseRightAll(); void slot_quit(bool); + void slot_closeAllFile(bool); void slot_batch_convert(); void slot_batch_rename(); @@ -160,6 +164,9 @@ public slots: void slot_clearWordHighlight(); void slot_clearMark(); + void slot_zoomValueChange(); + + protected: void closeEvent(QCloseEvent *event) override; void dragEnterEvent(QDragEnterEvent* event) override; @@ -239,7 +246,7 @@ private slots: void slot_aboutNdd(); void slot_fileChange(QString filePath); void slot_tabBarDoubleClicked(int index); - void slot_toLightBlueStyle(); + /*void slot_toLightBlueStyle(); void slot_toDefaultStyle(); void slot_toThinBlueStyle(); void slot_toRiceYellow(); @@ -247,7 +254,7 @@ private slots: void slot_toSilverStyle(); void slot_toDarkStyle(); void slot_toLavenderBlush(); - void slot_toMistyRose(); + void slot_toMistyRose();*/ void slot_register(); void slot_slectionChanged(); @@ -258,7 +265,7 @@ private slots: void slot_tabFormatChange(bool tabLenChange, bool useTabChange); void slot_searchResultShow(); void slot_saveFile(QString fileName, ScintillaEditView * pEdit); - void slot_skinStyleGroup(QAction * action); + /*void slot_skinStyleGroup(QAction * action);*/ void slot_changeIconSize(QAction * action); void slot_langFormat(); @@ -312,6 +319,16 @@ private slots: void slot_markColorGroup(QAction * action); void slot_loadMarkColor(); void slot_saveSearchHistory(); + void slot_fileListView(bool check); + void slot_fileListItemDoubleClick(QListWidgetItem* item); + void slot_showToolBar(bool); + void slot_dynamicLoadToolMenu(); + void slot_batchFind(); + void slot_pluginMgr(); + void slot_showWebAddr(bool check); + void onPlugWork(bool check); + + private: void initFindResultDockWin(); void enableEditTextChangeSign(ScintillaEditView * pEdit); @@ -392,8 +409,19 @@ private: void registerEscKeyShort(QWidget * parent); void closeAllFileWhenQuit(bool isQuit=false); + void initFileListDockWin(); + void addFileListView(QString file, QWidget* pw); + void delFileListView(QString file); + void fileListSetCurItem(QString filePath); + void syncFileTabToListView(); + void setZoomLabelValue(int zoomValue); + void zoomto(int zoomValue); + void tabClose(QWidget* pEdit); - + void init_toolsMenu(); + void loadPluginLib(); + void loadPluginProcs(QString strLibDir, QMenu* pMenu); + void onPlugFound(NDD_PROC_DATA& procData, QMenu* pUserData); private: Ui::CCNotePad ui; @@ -401,12 +429,16 @@ private: QLabel* m_lineEndLabel; QLabel* m_lineNumLabel; QLabel* m_langDescLabel; + QLabel* m_zoomLabel; QMenu* m_tabRightClickMenu; QDockWidget* m_dockSelectTreeWin; FindResultWin* m_pResultWin; + QPointer m_dockFileListWin; + FileListView* m_fileListView; + //一个用于查找,一个用于排序 QMap m_receneOpenFile; QList m_receneOpenFileList; @@ -431,6 +463,7 @@ private: QString m_cmpRightFilePath; QPointer m_pFindWin; + QPointer m_columnEditWin; QSharedMemory* m_shareMem; @@ -506,12 +539,26 @@ private: QToolButton* m_transcode; QToolButton* m_rename; + + QPointer m_batchFindWin; + int m_curIconSize; int m_curColorIndex; + + bool m_isInReloadFile; + + bool m_isToolMenuLoaded; + + bool m_isInitBookMarkAct; + + QListm_styleMarkActList; + QList m_pluginList; + public: static QString s_lastOpenDirPath; static int s_restoreLastFile; //自动恢复上次打开的文件 static int s_curStyleId; static int s_curMarkColorId; + static int s_hightWebAddr;//高亮网页地址 }; diff --git a/src/cceditor/ccnotepad.ui b/src/cceditor/ccnotepad.ui index f29dbea..62847ef 100755 --- a/src/cceditor/ccnotepad.ui +++ b/src/cceditor/ccnotepad.ui @@ -224,8 +224,11 @@ - + + + + @@ -466,20 +469,6 @@ Set(&T) - - - Style - - - - - - - - - - - Language @@ -487,20 +476,10 @@ - - - Format Language - - - - - - - @@ -515,6 +494,11 @@ + + + Tools(&O) + + @@ -522,6 +506,7 @@ + @@ -2007,6 +1992,38 @@ Clear History + + + true + + + FileListView + + + + + true + + + true + + + Show ToolBar + + + + + Batch Find + + + + + true + + + Show Web Addr(Not recommended) + + @@ -2637,134 +2654,6 @@ - - actionDefaultStyle - triggered() - CCNotePad - slot_toDefaultStyle() - - - -1 - -1 - - - 554 - 379 - - - - - actionLightBlueStyle - triggered() - CCNotePad - slot_toLightBlueStyle() - - - -1 - -1 - - - 554 - 379 - - - - - actionThinBlue - triggered() - CCNotePad - slot_toThinBlueStyle() - - - -1 - -1 - - - 554 - 379 - - - - - actionRiceYellow - triggered() - CCNotePad - slot_toRiceYellow() - - - -1 - -1 - - - 554 - 379 - - - - - actionYellow - triggered() - CCNotePad - slot_toYellow() - - - -1 - -1 - - - 554 - 379 - - - - - actionSilver - triggered() - CCNotePad - slot_toSilverStyle() - - - -1 - -1 - - - 554 - 379 - - - - - actionLavenderBlush - triggered() - CCNotePad - slot_toLavenderBlush() - - - -1 - -1 - - - 554 - 379 - - - - - actionMistyRose - triggered() - CCNotePad - slot_toMistyRose() - - - -1 - -1 - - - 554 - 379 - - - actionEnglish triggered() @@ -3453,54 +3342,6 @@ - - actionFormat_Xml - triggered() - CCNotePad - slot_formatXml() - - - -1 - -1 - - - 728 - 394 - - - - - actionFormat_Json - triggered() - CCNotePad - slot_formatJson() - - - -1 - -1 - - - 728 - 394 - - - - - actionDark - triggered() - CCNotePad - slot_toDarkStyle() - - - -1 - -1 - - - 728 - 394 - - - actionClear_History triggered() @@ -3517,6 +3358,54 @@ + + actionFileListView + triggered(bool) + CCNotePad + slot_fileListView(bool) + + + -1 + -1 + + + 728 + 394 + + + + + actionShow_ToolBar + triggered(bool) + CCNotePad + slot_showToolBar(bool) + + + -1 + -1 + + + 728 + 394 + + + + + actionShow_Web_Addr + triggered(bool) + CCNotePad + slot_showWebAddr(bool) + + + -1 + -1 + + + 728 + 394 + + + slot_actionNewFile_toggle(bool) @@ -3615,5 +3504,8 @@ slot_allWhite(bool) slot_toDarkStyle() slot_clearHistoryOpenList() + slot_fileListView(bool) + slot_showToolBar(bool) + slot_showWebAddr(bool) diff --git a/src/cceditor/filemanager.cpp b/src/cceditor/filemanager.cpp index 08c3091..f93a9c9 100755 --- a/src/cceditor/filemanager.cpp +++ b/src/cceditor/filemanager.cpp @@ -18,9 +18,9 @@ FileManager::~FileManager() { } -ScintillaEditView* FileManager::newEmptyDocument() +ScintillaEditView* FileManager::newEmptyDocument(bool isBigText) { - ScintillaEditView* pEdit = new ScintillaEditView(nullptr); + ScintillaEditView* pEdit = new ScintillaEditView(nullptr, isBigText); return pEdit; } @@ -500,6 +500,7 @@ int FileManager::loadFilePreNextPage(int dir, QString& filePath, HexFileMgr* & const int ONE_PAGE_TEXT_SIZE = 200 * 1024; //加载下一页或者上一页。(文本模式) +//返回值:0表示成功 int FileManager::loadFilePreNextPage(int dir, QString& filePath, TextFileMgr* & textFileOut) { if (m_bigTxtFileMgr.contains(filePath)) @@ -802,7 +803,7 @@ bool FileManager::loadFileData(QString filePath, HexFileMgr* & hexFileOut) } //加载大文本文件。从0开始读取ONE_PAGE_TEXT_SIZE 500K的内容 -bool FileManager::loadFileData(QString filePath, TextFileMgr* & textFileOut) +bool FileManager::loadFileData(QString filePath, TextFileMgr* & textFileOut, RC_LINE_FORM & lineEnd) { QFile *file = new QFile(filePath); @@ -834,6 +835,22 @@ bool FileManager::loadFileData(QString filePath, TextFileMgr* & textFileOut) { //给后面的字符填\0,让字符串正常结尾\0 buf[ret - preLineEndPos] = '\0'; + + if (ret - preLineEndPos >= 2) + { + if (buf[ret - preLineEndPos - 1] == '\n' && buf[ret - preLineEndPos - 2] == '\r') + { + lineEnd = DOS_LINE; + } + else if (buf[ret - preLineEndPos - 1] == '\n') + { + lineEnd = UNIX_LINE; + } + else if (buf[ret - preLineEndPos - 1] == '\r') + { + lineEnd = MAC_LINE; + } + } } TextFileMgr* txtFile = nullptr; diff --git a/src/cceditor/filemanager.h b/src/cceditor/filemanager.h index 65ff725..78a9f9f 100755 --- a/src/cceditor/filemanager.h +++ b/src/cceditor/filemanager.h @@ -96,7 +96,7 @@ class FileManager:public QObject { Q_OBJECT public: - ScintillaEditView* newEmptyDocument(); + ScintillaEditView* newEmptyDocument(bool isBigText = false); ScintillaHexEditView * newEmptyHexDocument(); @@ -122,7 +122,7 @@ public: bool loadFileData(QString filePath, HexFileMgr * & hexFileOut); - bool loadFileData(QString filePath, TextFileMgr *& textFileOut); + bool loadFileData(QString filePath, TextFileMgr *& textFileOut, RC_LINE_FORM & lineEnd); HexFileMgr* getHexFileHand(QString filepath); diff --git a/src/columnedit.cpp b/src/columnedit.cpp index cba68be..50fd9ae 100755 --- a/src/columnedit.cpp +++ b/src/columnedit.cpp @@ -7,6 +7,7 @@ ColumnEdit::ColumnEdit(QWidget *parent) ui.setupUi(this); connect(ui.addPrefix, &QCheckBox::stateChanged, this, &ColumnEdit::slot_addPrefix); + connect(ui.is16, &QRadioButton::clicked, this, &ColumnEdit::slot_bigChar); } ColumnEdit::~ColumnEdit() @@ -48,6 +49,11 @@ void ColumnEdit::slot_addPrefix(int s) } } +void ColumnEdit::slot_bigChar(bool isCheck) +{ + ui.capital->setEnabled(isCheck); +} + //Զǰڵ״̬ QWidget* ColumnEdit::autoAdjustCurrentEditWin() { @@ -83,8 +89,9 @@ void ColumnEdit::slot_ok() int initNum = 0; int inc = ui.incNum->value(); int repeNum = ui.repeNum->value(); - bool addPrefix = ui.addPrefix->isChecked(); + bool isAddPrefix = ui.addPrefix->isChecked(); QString prefix = ui.prefix->text(); + bool isCapital = ui.capital->isChecked(); //Dzıģʽ if (ui.textGroupBox->isChecked()) @@ -124,13 +131,14 @@ void ColumnEdit::slot_ok() { text = QString::number(num, numType); - if (addPrefix) + if (isAddPrefix) { text = prefix + text; } } else { + //ҪӸʾ QApplication::beep(); return; } @@ -138,6 +146,45 @@ void ColumnEdit::slot_ok() pEdit->execute(SCI_BEGINUNDOACTION); + if (ui.textGroupBox->isChecked()) + { + if (pEdit->execute(SCI_SELECTIONISRECTANGLE) || pEdit->execute(SCI_GETSELECTIONS) > 1) + { + ColumnModeInfos colInfos = pEdit->getColumnModeSelectInfo(); + std::sort(colInfos.begin(), colInfos.end(), SortInPositionOrder()); + + QByteArray bytes = text.toUtf8(); + pEdit->columnReplace(colInfos, bytes); + std::sort(colInfos.begin(), colInfos.end(), SortInSelectOrder()); + pEdit->setMultiSelections(colInfos); + + return; + } + } + else + { + if (pEdit->execute(SCI_SELECTIONISRECTANGLE) || pEdit->execute(SCI_GETSELECTIONS) > 1) + { + ColumnModeInfos colInfos = pEdit->getColumnModeSelectInfo(); + + // If there is no column mode info available, no need to do anything + // If required a message can be shown to user, that select column properly or something similar + if (colInfos.size() > 0) + { + std::sort(colInfos.begin(), colInfos.end(), SortInPositionOrder()); + QByteArray bytes; + if (isAddPrefix) + { + bytes = prefix.toUtf8(); + } + pEdit->columnReplace(colInfos, initNum, inc, repeNum, numType, isCapital, bytes); + std::sort(colInfos.begin(), colInfos.end(), SortInSelectOrder()); + pEdit->setMultiSelections(colInfos); + } + return; + } + } + auto cursorPos = pEdit->execute(SCI_GETCURRENTPOS); auto cursorCol = pEdit->execute(SCI_GETCOLUMN, cursorPos); auto cursorLine = pEdit->execute(SCI_LINEFROMPOSITION, cursorPos); @@ -196,10 +243,25 @@ void ColumnEdit::slot_ok() } + + if (numType != 16) + { text = QString::number(initNum, numType); + } + else + { + if (isCapital) + { + text = QString::number(initNum, numType).toUpper(); + } + else + { + text = QString::number(initNum, numType); + } + } - if (addPrefix) + if (isAddPrefix) { text = prefix + text; } @@ -207,4 +269,4 @@ void ColumnEdit::slot_ok() } pEdit->execute(SCI_ENDUNDOACTION); -} \ No newline at end of file +} diff --git a/src/columnedit.h b/src/columnedit.h index c77f5ed..d650e47 100755 --- a/src/columnedit.h +++ b/src/columnedit.h @@ -24,6 +24,7 @@ private slots: void slot_insertNumEnable(bool check); void slot_insertTextEnable(bool check); void slot_addPrefix(int s); + void slot_bigChar(bool isCheck); void slot_ok(); private: diff --git a/src/columnedit.ui b/src/columnedit.ui index 30f3305..94f0329 100755 --- a/src/columnedit.ui +++ b/src/columnedit.ui @@ -48,7 +48,11 @@ - + + + 1024 + + @@ -260,6 +264,19 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -267,6 +284,19 @@ + + + + false + + + Capital + + + true + + + diff --git a/src/encodeconvert.cpp b/src/encodeconvert.cpp index e6782af..c17022e 100755 --- a/src/encodeconvert.cpp +++ b/src/encodeconvert.cpp @@ -97,15 +97,7 @@ void EncodeConvert::slot_itemClicked(QTreeWidgetItem* item, int /*column*/) } path = QString("%1").arg(it->data(0, Qt::ToolTipRole).toString()); -#ifdef _WIN32 - path = path.replace("/", "\\"); - cmd = QString("explorer.exe /select,%1").arg(path); -#else - path = path.replace("\\", "/"); - cmd = QString("open -R %1").arg(path); -#endif - QProcess process; - process.startDetached(cmd); + showFileInExplorer(path); }); } m_menu->move(QCursor::pos()); diff --git a/src/filelistview.cpp b/src/filelistview.cpp new file mode 100755 index 0000000..d6663e5 --- /dev/null +++ b/src/filelistview.cpp @@ -0,0 +1,116 @@ +#include "filelistview.h" +#include "rcglobal.h" +#include "ccnotepad.h" +#include +#include + + +//ʾļԺ󣬰ļڸб + +FileListView::FileListView(QWidget *parent) + : QWidget(parent), m_pNotepad(nullptr) +{ + ui.setupUi(this); + + connect(ui.filelistWidget, &QListWidget::itemDoubleClicked, this, &FileListView::itemDoubleClicked); + + setContextMenuPolicy(Qt::CustomContextMenu); //öֵ + + connect(this, &QListWidget::customContextMenuRequested, this, &FileListView::slot_ShowPopMenu); +} + +FileListView::~FileListView() +{ + m_fileEditMap.clear(); +} + +void FileListView::setNotepadWin(QWidget* pNotepad) +{ + m_pNotepad = pNotepad; +} + +//Ҽ˵ +void FileListView::slot_ShowPopMenu(const QPoint& pos) +{ + QListWidgetItem* curItem = ui.filelistWidget->itemAt(pos); + if (curItem != nullptr) + { + QMenu* menu = new QMenu(this); + + QAction* actionAdd = menu->addAction(tr("Show File in Explorer"), this, [&]() { + showFileInExplorer(curItem->text()); + }); + + menu->addAction(tr("Close File"), this, [&]() { + + QString filePath = curItem->text(); + + if (m_fileEditMap.contains(filePath)) + { + CCNotePad* pNotePad = dynamic_cast(m_pNotepad); + + if (m_pNotepad != nullptr) + { + pNotePad->closeFileByEditWidget(m_fileEditMap.value(curItem->text()).pEditWidget); + } + //עﲻҪɾm_fileEditMapԪأΪcloseFileByEditWidgetá + } + }); + + //ûƱʾǶitemڶӦļֻռλ + if (curItem->text().isEmpty()) + { + actionAdd->setEnabled(false); + } + + if (menu) + { + menu->setAttribute(Qt::WA_DeleteOnClose); + menu->exec(QCursor::pos()); + } + } +} + +void FileListView::delFileItem(QString & filePath) +{ + if (m_fileEditMap.contains(filePath)) + { + m_fileEditMap.remove(filePath); + QList items = ui.filelistWidget->findItems(filePath, Qt::MatchFixedString); + + if (!items.isEmpty()) + { + delete items.at(0); + } + + } +} + +QWidget* FileListView::getWidgetByFilePath(QString filePath) +{ + if (m_fileEditMap.contains(filePath)) + { + return m_fileEditMap.value(filePath).pEditWidget; + } + return nullptr; +} + +void FileListView::setCurItem(QString filePath) +{ + if (m_fileEditMap.contains(filePath)) + { + ui.filelistWidget->setCurrentItem(m_fileEditMap.value(filePath).pListItem); + } +} + +void FileListView::addFileItem(QString& filePath, QWidget* edit) +{ + if (!m_fileEditMap.contains(filePath)) + { + QListWidgetItem* newItem = new QListWidgetItem(filePath); + ui.filelistWidget->addItem(newItem); + + m_fileEditMap.insert(filePath, FileListItemData(edit, newItem)); + } +} + diff --git a/src/filelistview.h b/src/filelistview.h new file mode 100755 index 0000000..32c2a49 --- /dev/null +++ b/src/filelistview.h @@ -0,0 +1,48 @@ +#pragma once + +#include +#include + +#include "ui_filelistview.h" + +struct FileListItemData { + QWidget* pEditWidget; + QListWidgetItem* pListItem; + + FileListItemData() = default; + FileListItemData(QWidget* pwid, QListWidgetItem* pItem) :pEditWidget(pwid),pListItem(pItem) + { + + } +}; + +class FileListView : public QWidget +{ + Q_OBJECT + +public: + FileListView(QWidget *parent = nullptr); + virtual ~FileListView(); + + void setNotepadWin(QWidget* pNotepad); + + void delFileItem(QString & filePath); + + QWidget* getWidgetByFilePath(QString filePath); + + void addFileItem(QString& filePath, QWidget* edit); + + void setCurItem(QString filePath); +signals: + void itemDoubleClicked(QListWidgetItem* item); + +private slots: + void slot_ShowPopMenu(const QPoint& pos); + +private: + Ui::FileListViewClass ui; + + QWidget* m_pNotepad; + + QMap m_fileEditMap; +}; diff --git a/src/filelistview.ui b/src/filelistview.ui new file mode 100755 index 0000000..b4b7074 --- /dev/null +++ b/src/filelistview.ui @@ -0,0 +1,43 @@ + + + FileListViewClass + + + + 0 + 0 + 550 + 693 + + + + FileListView + + + + 0 + + + 0 + + + 0 + + + 0 + + + 1 + + + 3 + + + + + + + + + + diff --git a/src/findresultwin.cpp b/src/findresultwin.cpp index 2cfb3bd..7d86701 100755 --- a/src/findresultwin.cpp +++ b/src/findresultwin.cpp @@ -373,11 +373,24 @@ void FindResultWin::highlightFindText(int index, QString &srcText, QString &find srcText.replace(pos, lens, QString("%1").arg(srcText.mid(pos,lens))); } +const int MAX_HEAD_LENTGH = 20; +const int MAX_TAIL_LENGTH = 80; + //更复杂的高亮:在全词语匹配,大小写敏感,甚至正则表达式情况下,上面的highlightFindText是不够的。需要精确定位 QString FindResultWin::highlightFindText(FindRecord& record) { QByteArray utf8bytes = record.lineContents.toUtf8(); + int lineLens = utf8bytes.length(); + + bool isNeedCut = false; + + //行太长的进行缩短显示 + if (lineLens > 300) + { + isNeedCut = true; + } + //高亮的开始、结束位置 int targetStart = record.pos - record.lineStartPos; int targetLens = record.end - record.pos; @@ -386,18 +399,72 @@ QString FindResultWin::highlightFindText(FindRecord& record) QString head; QString src; QString tail; - if (BLACK_SE != StyleSet::getCurrentSytleId()) + if (!StyleSet::isCurrentDeepStyle()) { + if (!isNeedCut) + { head = QString(utf8bytes.mid(0, targetStart)).toHtmlEscaped(); src = QString("%1").arg(QString(utf8bytes.mid(targetStart, targetLens)).toHtmlEscaped()); tail = QString(utf8bytes.mid(tailStart)).toHtmlEscaped(); } else { - head = QString("%1").arg(QString(utf8bytes.mid(0, targetStart)).toHtmlEscaped()); + head = QString(utf8bytes.mid(0, targetStart)); + if (head.size() > MAX_HEAD_LENTGH) + { + head = (head.mid(0, MAX_HEAD_LENTGH) + "...").toHtmlEscaped(); + } + else + { + head = head.toHtmlEscaped(); + } src = QString("%1").arg(QString(utf8bytes.mid(targetStart, targetLens)).toHtmlEscaped()); + tail = QString(utf8bytes.mid(tailStart)); + if (tail > MAX_TAIL_LENGTH) + { + tail = (tail.mid(0, MAX_TAIL_LENGTH) + "...").toHtmlEscaped(); + } + else + { + tail = tail.toHtmlEscaped(); + } + } + } + else + { + if (!isNeedCut) + { + head = QString("%1").arg(QString(utf8bytes.mid(0, targetStart)).toHtmlEscaped()); + src = QString("%1").arg(QString(utf8bytes.mid(targetStart, targetLens)).toHtmlEscaped()); tail = QString("%1").arg(QString(utf8bytes.mid(tailStart)).toHtmlEscaped()); } + else + { + QString headContens = QString(utf8bytes.mid(0, targetStart)); + if (headContens.size() > MAX_HEAD_LENTGH) + { + headContens = (headContens.mid(0, MAX_HEAD_LENTGH) + "...").toHtmlEscaped(); + } + else + { + headContens = headContens.toHtmlEscaped(); + } + + head = QString("%1").arg(headContens); + src = QString("%1").arg(QString(utf8bytes.mid(targetStart, targetLens)).toHtmlEscaped()); + + QString tailContens = QString(utf8bytes.mid(tailStart)); + if (tailContens > MAX_TAIL_LENGTH) + { + tailContens = (tailContens.mid(0, MAX_TAIL_LENGTH) + "...").toHtmlEscaped(); + } + else + { + tailContens = tailContens.toHtmlEscaped(); + } + tail = QString("%1").arg(tailContens); + } + } return QString("%1%2%3").arg(head).arg(src).arg(tail); } @@ -408,10 +475,20 @@ void FindResultWin::appendResultsToShow(FindRecords* record) { return; } + QString findTitle = tr("Search \"%1\" (%2 hits)").arg(record->findText.toHtmlEscaped()).arg(record->records.size()); QStandardItem* titleItem = new QStandardItem(findTitle); + + if (!StyleSet::isCurrentDeepStyle()) + { setItemBackground(titleItem, QColor(0xbbbbff)); + } + else + { + setItemBackground(titleItem, QColor(0xd5ffd5)); + } + m_model->insertRow(0, titleItem); titleItem->setData(QVariant(true), ResultItemRoot); @@ -429,11 +506,19 @@ void FindResultWin::appendResultsToShow(FindRecords* record) return; } - QString desc = tr("%1 (%2 hits)").arg(record->findFilePath.toHtmlEscaped()).arg(record->records.size()); + QString desc; + if (!StyleSet::isCurrentDeepStyle()) + { + desc = tr("%1 (%2 hits)").arg(record->findFilePath.toHtmlEscaped()).arg(record->records.size()); + } + else + { + desc = tr("%1 (%2 hits)").arg(record->findFilePath.toHtmlEscaped()).arg(record->records.size()); + } QStandardItem* descItem = new QStandardItem(desc); - if (BLACK_SE != StyleSet::getCurrentSytleId()) + if (!StyleSet::isCurrentDeepStyle()) { setItemBackground(descItem, QColor(0xd5ffd5)); } @@ -460,7 +545,7 @@ void FindResultWin::appendResultsToShow(FindRecords* record) QString richText = highlightFindText(v); - QString text = tr("Line %1 : %2").arg(v.lineNum + 1).arg(richText); + QString text = tr("Line %1 : %2").arg(v.lineNum + 1).arg(richText); QStandardItem* childItem = new QStandardItem(text); childItem->setData(QVariant(v.pos), ResultItemPos); @@ -513,7 +598,7 @@ void FindResultWin::appendResultsToShow(QVector* record, int hits, QStandardItem* descItem = new QStandardItem(desc); - if (BLACK_SE != StyleSet::getCurrentSytleId()) + if (!StyleSet::isCurrentDeepStyle()) { setItemBackground(descItem, QColor(0xd5ffd5)); } @@ -542,7 +627,7 @@ void FindResultWin::appendResultsToShow(QVector* record, int hits, FindRecord v = pr->records.at(i); QString richText = highlightFindText(v); - QString text = QString("Line %1 : %2").arg(v.lineNum + 1).arg(richText); + QString text = QString("Line %1 : %2").arg(v.lineNum + 1).arg(richText); QStandardItem* childItem = new QStandardItem(text); childItem->setData(QVariant(v.pos), ResultItemPos); diff --git a/src/findwin.cpp b/src/findwin.cpp index e5a8a78..7a55059 100755 --- a/src/findwin.cpp +++ b/src/findwin.cpp @@ -167,7 +167,7 @@ void FindWin::setFindHistory(QList* findHistory) } //标记高亮所有word单词 -void FindWin::markAllWord(QString & word) +int FindWin::markAllWord(QString & word) { ui.markTextBox->setCurrentText(word); ui.findinfilesTab->setCurrentIndex(3); @@ -175,7 +175,7 @@ void FindWin::markAllWord(QString & word) //但是好像没有一个现成的方法来判断word中的字符。暂时不做全词匹配 ui.markMatchWholeBox->setChecked(false); ui.markMatchCaseBox->setChecked(true); - slot_markAll(); + return markAll(); } //删除行首尾的空白字符 @@ -732,7 +732,7 @@ void FindWin::findNext() void FindWin::findPrev() { slot_findPrev(); -} + } /*处理查找时零长的问题。一定要处理,否则会死循环,因为每次都在原地查找。 * 就是把下次查找的startpos往前一个,否则每次都从这个startpos找到自己 @@ -1014,13 +1014,101 @@ void FindWin::addCurFindRecord(ScintillaEditView* pEdit, FindRecords& recordRet, recordRet.records.append(aRecord); } -void FindWin::slot_findAllInCurDoc() +//在后台查找 +int FindWin::findAtBack(QString keyword) +{ + this->setCurrentTab(FIND_TAB); + ui.findComboBox->setCurrentText(keyword); + ui.findBackwardBox->setChecked(false); + ui.findMatchCaseBox->setChecked(true); + ui.findWrapBox->setChecked(false); + ui.findMatchWholeBox->setChecked(false); + ui.findModeNormalBt->setChecked(true); + + m_isStatic = true; + int times = findAllInCurDoc(); + m_isStatic = false; + + return times; +} + +//在后台替换 +int FindWin::replaceAtBack(QStringList& keyword, QStringList& replace) +{ + assert(keyword.size() == replace.size()); + + this->setCurrentTab(REPLACE_TAB); + + QWidget* pw = autoAdjustCurrentEditWin(); + ScintillaEditView* pEdit = dynamic_cast(pw); + if (pEdit != nullptr) + { + if (pEdit->isReadOnly()) + { + ui.statusbar->showMessage(tr("The ReadOnly document does not allow replacement."), 8000); + QApplication::beep(); + return 0; + } + } + + ui.replaceBackwardBox->setChecked(false); + ui.replaceMatchWholeBox->setChecked(false); + ui.replaceMatchCaseBox->setChecked(true); + ui.replaceWrapBox->setChecked(false); + ui.replaceModeNormalBox->setChecked(true); + + m_isStatic = true; + int times = 0; + + pEdit->execute(SCI_BEGINUNDOACTION); + + ProgressWin* loadFileProcessWin = new ProgressWin(this); + + loadFileProcessWin->setWindowModality(Qt::WindowModal); + + loadFileProcessWin->info(tr("total %1 keyword, please wait ...").arg(keyword.size())); + + loadFileProcessWin->setTotalSteps(keyword.size()); + + loadFileProcessWin->show(); + + for (int i = 0; i < keyword.size(); ++i) + { + if (loadFileProcessWin->isCancel()) + { + break; + } + + ui.replaceTextBox->setCurrentText(keyword.at(i)); + ui.replaceWithBox->setCurrentText(replace.at(i)); + + updateParameterFromUI(); + + QString whatFind = ui.replaceTextBox->currentText(); + QString replaceText = ui.replaceWithBox->currentText(); + + times += doReplaceAll(pEdit, whatFind, replaceText, false); + + loadFileProcessWin->moveStep(); + + QCoreApplication::processEvents(); + } + delete loadFileProcessWin; + + pEdit->execute(SCI_ENDUNDOACTION); + + m_isStatic = false; + + return times; +} + +int FindWin::findAllInCurDoc() { if (ui.findComboBox->currentText().isEmpty()) { ui.statusbar->showMessage(tr("what find is null !"), 8000); QApplication::beep(); - return; + return 0; } QWidget* pw = autoAdjustCurrentEditWin(); @@ -1029,9 +1117,12 @@ void FindWin::slot_findAllInCurDoc() { if (pEdit->isReadOnly()) { - ui.statusbar->showMessage(tr("The ReadOnly document does not allow this operation."), 8000); + if (!m_isStatic) + { + ui.statusbar->showMessage(tr("The ReadOnly document does not allow this operation."), 8000); + } QApplication::beep(); - return; + return 0; } FindRecords results; @@ -1057,18 +1148,21 @@ void FindWin::slot_findAllInCurDoc() convertExtendedToString(whatFind, extendFind); whatFind = extendFind; } - + //这里的forward一定要是true。回环一定是false if (!pEdit->findFirst(whatFind, m_re, m_cs, m_wo, false, true, FINDNEXTTYPE_FINDNEXT, 0, 0)) { ui.statusbar->showMessage(tr("cant't find text \'%1\'").arg(m_expr), 8000); - QApplication::beep(); - - emit sign_findAllInCurDoc(&results); + + if (!m_isStatic) + { + QApplication::beep(); + emit sign_findAllInCurDoc(&results); + } m_isFindFirst = true; - return; + return 0; } else { @@ -1097,12 +1191,23 @@ void FindWin::slot_findAllInCurDoc() ui.statusbar->showMessage(tr("find finished, total %1 found!").arg(replaceNums), 10000); emit sign_findAllInCurDoc(&results); + + return replaceNums; } else { - ui.statusbar->showMessage(tr("The mode of the current document does not allow this operation."), 8000); - QApplication::beep(); + if (!m_isStatic) + { + ui.statusbar->showMessage(tr("The mode of the current document does not allow this operation."), 8000); + QApplication::beep(); + } } + return 0; +} + +void FindWin::slot_findAllInCurDoc() +{ + findAllInCurDoc(); } void FindWin::slot_findAllInOpenDoc() @@ -1533,14 +1638,17 @@ struct FindReplaceInfo }; //返回值替换数量 -int FindWin::doReplaceAll(ScintillaEditView* pEdit, QString &whatFind, QString& replaceText) +int FindWin::doReplaceAll(ScintillaEditView* pEdit, QString &whatFind, QString& replaceText, bool isCombineUndo) { int replaceNums = 0; int srcPostion = pEdit->execute(SCI_GETCURRENTPOS); int firstDisLineNum = pEdit->execute(SCI_GETFIRSTVISIBLELINE); + if (isCombineUndo) + { pEdit->execute(SCI_BEGINUNDOACTION); + } int flags = buildSearchFlags(m_re, m_cs, m_wo, false, true, FINDNEXTTYPE_REPLACENEXT, 0, 0); @@ -1601,8 +1709,10 @@ int FindWin::doReplaceAll(ScintillaEditView* pEdit, QString &whatFind, QString& findReplaceInfo._endRange += replaceDelta; //adjust end of range in case of replace } - + if (isCombineUndo) + { pEdit->execute(SCI_ENDUNDOACTION); + } pEdit->execute(SCI_GOTOPOS, srcPostion); pEdit->execute(SCI_SETFIRSTVISIBLELINE, firstDisLineNum); @@ -1613,19 +1723,17 @@ int FindWin::doReplaceAll(ScintillaEditView* pEdit, QString &whatFind, QString& return replaceNums; } -//替换当前文档里面的所有。之前的要慢,是因为qscintilla中实时计算了行在屏幕需要的长度。 -//大量的这种计算一行实时长度的操作,非常耗时。查找、标记均不耗时,只有替换修改了文本才耗时。 -void FindWin::slot_replaceAll() +int FindWin::replaceAll() { if (ui.replaceTextBox->currentText().isEmpty()) { ui.statusbar->showMessage(tr("what find is null !"), 8000); - return; + return 0; } - if (!m_isStatic && QMessageBox::Yes != QMessageBox::question(this, tr("Replace All current Doc"), tr("Are you sure replace all occurrences in current documents?"))) + if (!m_isStatic && QMessageBox::Yes != QMessageBox::question(this, tr("Replace All current Doc"), tr("Are you sure replace all occurrences in current documents?"))) { - return; + return 0; } QWidget* pw = autoAdjustCurrentEditWin(); @@ -1636,7 +1744,7 @@ void FindWin::slot_replaceAll() { ui.statusbar->showMessage(tr("The ReadOnly document does not allow replacement."), 8000); QApplication::beep(); - return; + return 0; } } updateParameterFromUI(); @@ -1659,6 +1767,15 @@ void FindWin::slot_replaceAll() //全部替换后,下次查找,必须算第一次查找 m_isFindFirst = true; ui.statusbar->showMessage(tr("replace finished, total %1 replaced!").arg(replaceNums), 10000); + + return replaceNums; +} + +//替换当前文档里面的所有。之前的要慢,是因为qscintilla中实时计算了行在屏幕需要的长度。 +//大量的这种计算一行实时长度的操作,非常耗时。查找、标记均不耗时,只有替换修改了文本才耗时。 +void FindWin::slot_replaceAll() +{ + replaceAll(); } void FindWin::slot_replaceAllInOpenDoc() @@ -1737,22 +1854,20 @@ void FindWin::slot_replaceAllInOpenDoc() ui.statusbar->showMessage(tr("Replace in Opened Files: %1 occurrences were replaced.").arg(replaceNums), 10000); } - -//标记高亮单词 -void FindWin::slot_markAll() +int FindWin::markAll() { if (ui.markTextBox->currentText().isEmpty()) { ui.statusbar->showMessage(tr("what mark is null !"), 8000); QApplication::beep(); - return; + return 0; } QWidget* pw = autoAdjustCurrentEditWin(); ScintillaEditView* pEdit = dynamic_cast(pw); if (pEdit != nullptr) { - FindRecords *results = new FindRecords; + FindRecords* results = new FindRecords; results->pEdit = pEdit; results->hightLightColor = CCNotePad::s_curMarkColorId; @@ -1778,8 +1893,8 @@ void FindWin::slot_markAll() if (!pEdit->findFirst(whatMark, m_re, m_cs, m_wo, false, true, FINDNEXTTYPE_FINDNEXT, 0, 0)) { ui.statusbar->showMessage(tr("cant't find text \'%1\'").arg(m_expr), 8000); - QApplication::beep(); - return; + //QApplication::beep(); + return 0; } else { @@ -1789,11 +1904,11 @@ void FindWin::slot_markAll() { ui.statusbar->showMessage(tr("cant't mark text \'%1\'").arg(m_expr), 8000); QApplication::beep(); - return; + return 0; } } - addCurFindRecord(pEdit, *results,true); + addCurFindRecord(pEdit, *results, true); ++replaceNums; @@ -1813,7 +1928,7 @@ void FindWin::slot_markAll() if (foundTextLen > 0) { - pEdit->execute(SCI_SETINDICATORCURRENT,CCNotePad::s_curMarkColorId); + pEdit->execute(SCI_SETINDICATORCURRENT, CCNotePad::s_curMarkColorId); pEdit->execute(SCI_INDICATORFILLRANGE, rs.pos, foundTextLen); } } @@ -1831,12 +1946,20 @@ void FindWin::slot_markAll() //全部替换后,下次查找,必须算第一次查找 m_isFindFirst = true; ui.statusbar->showMessage(tr("mark finished, total %1 found!").arg(replaceNums), 10000); + + return replaceNums; } else { ui.statusbar->showMessage(tr("The mode of the current document does not allow mark."), 8000); QApplication::beep(); } + return 0; +} +//标记高亮单词 +void FindWin::slot_markAll() +{ + markAll(); } //取消高亮当前关键字 diff --git a/src/findwin.h b/src/findwin.h index e8a6332..c32a7d4 100755 --- a/src/findwin.h +++ b/src/findwin.h @@ -62,13 +62,17 @@ public: void setFindText(QString & text); void disableReplace(); void setFindHistory(QList* findHistory); - void markAllWord(QString& word); + int markAllWord(QString& word); void removeLineHeadEndBlank(int mode); static void showCallTip(QsciScintilla * pEdit, int pos); void removeEmptyLine(bool isBlankContained); void findNext(); void findPrev(); void setFindBackward(bool isBackward); + int findAtBack(QString keyword); + int replaceAtBack(QStringList& keyword, QStringList& replace); + + protected: @@ -108,8 +112,13 @@ private: bool replace(ScintillaEditView* pEdit); - int doReplaceAll(ScintillaEditView * pEdit, QString& whatFind, QString& replaceText); + int doReplaceAll(ScintillaEditView * pEdit, QString& whatFind, QString& replaceText, bool isCombineUndo = true); + int replaceAll(); + + int markAll(); + + int findAllInCurDoc(); private slots: @@ -198,7 +207,6 @@ private: ScintillaEditView* pEditTemp; - QWidget* m_curEditWin; bool m_isStatic;//是否静默处理,不弹确认对话框 diff --git a/src/findwin.ui b/src/findwin.ui index d01419f..a985552 100755 --- a/src/findwin.ui +++ b/src/findwin.ui @@ -6,16 +6,10 @@ 0 0 - 589 - 362 + 633 + 384 - - - 1100 - 500 - - MainWindow @@ -24,18 +18,18 @@ :/Resources/edit/global/ndd.ico:/Resources/edit/global/ndd.ico - + 3 - 2 + 3 2 - 0 + 2 @@ -53,12 +47,21 @@ find + + 2 + + + + 0 + 0 + + Find what : @@ -72,6 +75,12 @@ 0 + + + 350 + 16777215 + + true @@ -90,7 +99,7 @@ 20 - 40 + 20 @@ -184,6 +193,19 @@ + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -192,7 +214,7 @@ - 0 + 200 28 @@ -208,7 +230,7 @@ - 0 + 200 28 @@ -222,6 +244,12 @@ + + + 200 + 0 + + Counter(T) @@ -234,7 +262,7 @@ - 0 + 200 34 @@ -248,7 +276,7 @@ - 0 + 200 34 @@ -260,6 +288,12 @@ + + + 200 + 0 + + Clear Result @@ -267,6 +301,12 @@ + + + 200 + 0 + + Close @@ -294,6 +334,9 @@ Replace + + 2 + @@ -302,6 +345,12 @@ + + + 0 + 0 + + Find what : @@ -315,6 +364,12 @@ 0 + + + 350 + 16777215 + + true @@ -329,6 +384,12 @@ + + + 0 + 0 + + Replace with : @@ -342,6 +403,12 @@ 0 + + + 350 + 16777215 + + true @@ -451,6 +518,19 @@ + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -459,9 +539,15 @@ + + + 0 + 0 + + - 0 + 200 28 @@ -480,7 +566,7 @@ - 0 + 200 28 @@ -499,7 +585,7 @@ - 0 + 200 28 @@ -518,7 +604,7 @@ - 0 + 200 34 @@ -536,6 +622,12 @@ 0 + + + 200 + 0 + + Close @@ -562,31 +654,50 @@ Dir Find - + + + 2 + - - + + + 0 + 0 + + Dest Dir : - + + + + 0 + 0 + + 250 0 + + + 350 + 16777215 + + - + @@ -599,18 +710,20 @@ - - - - + + + 0 + 0 + + Find what : - + @@ -618,6 +731,12 @@ 0 + + + 350 + 16777215 + + true @@ -628,77 +747,121 @@ - - - - - - Replace with : - - - - - - - - 250 - 0 - - - - true - - - - - - - - - - - File Type - - - - + + + false + + + 0 + 0 + + - 250 + 300 0 + + + 350 + 16777215 + + *.c:*.cpp:*.h - - - - - - - - Skip Dir Name - - - - - - - false - - - debug:Debug:.vs:.git:.svn - - - - + + + + + 300 + 0 + + + + + 350 + 16777215 + + + + true + + + + + + + + 0 + 0 + + + + File Type : + + + + + + + + 0 + 0 + + + + Replace with : + + + + + + + + 0 + 0 + + + + Skip Dir Name : + + + + + + + false + + + + 0 + 0 + + + + + 300 + 0 + + + + + 350 + 16777215 + + + + debug:Debug:.vs:.git:.svn + + @@ -710,7 +873,7 @@ 20 - 40 + 20 @@ -737,21 +900,21 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - + + + + Qt::Vertical + + + + 20 + 20 + + + + @@ -887,7 +1050,7 @@ - 160 + 200 28 @@ -899,14 +1062,14 @@ - + 0 0 - 160 + 200 28 @@ -918,14 +1081,14 @@ - + 0 0 - 160 + 200 28 @@ -937,14 +1100,14 @@ - + 0 0 - 160 + 200 28 @@ -975,12 +1138,21 @@ Mark + + 2 + + + + 0 + 0 + + Mark What @@ -994,6 +1166,12 @@ 0 + + + 350 + 16777215 + + true @@ -1012,7 +1190,7 @@ 20 - 40 + 20 @@ -1043,7 +1221,7 @@ 20 - 40 + 20 @@ -1085,15 +1263,34 @@ + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + 0 + 0 + + - 0 + 200 28 @@ -1104,9 +1301,15 @@ + + + 0 + 0 + + - 0 + 200 28 @@ -1117,9 +1320,15 @@ + + + 0 + 0 + + - 0 + 200 28 @@ -1138,7 +1347,7 @@ - 0 + 200 28 @@ -1182,7 +1391,6 @@ findWrapBox findModeNormalBt findModeRegularBt - findinfilesTab replaceTextBox replaceWithBox replaceBackwardBox @@ -1199,7 +1407,6 @@ destFindDir selectDir dirFindWhat - dirReplaceWhat dealFileType fileType dirFindMatchWholeBox diff --git a/src/include/pluginGl.h b/src/include/pluginGl.h new file mode 100755 index 0000000..069f6c2 --- /dev/null +++ b/src/include/pluginGl.h @@ -0,0 +1,27 @@ +#pragma once +#include + +#define NDD_EXPORTDLL + +#if defined(Q_OS_WIN) +#if defined(NDD_EXPORTDLL) +#define NDD_EXPORT __declspec(dllexport) +#else +#define NDD_EXPORT __declspec(dllimport) +#endif +#endif + +struct ndd_proc_data +{ + QString m_strPlugName; // ѡ + QString m_strFilePath; //lib ȫ·ѡ + QString m_strComment; //˵ + QString m_version; //汾롣ѡ + QString m_auther;//ơѡ +}; + + +typedef struct ndd_proc_data NDD_PROC_DATA; + +typedef bool (*NDD_PROC_IDENTIFY_CALLBACK)(NDD_PROC_DATA* pProcData); +typedef void (*NDD_PROC_FOUND_CALLBACK)(NDD_PROC_DATA* pProcData, void* pUserData); diff --git a/src/main.cpp b/src/main.cpp index a7d30c4..0cb48fb 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -135,6 +135,18 @@ int main(int argc, char *argv[]) QStringList arguments = QCoreApplication::arguments(); +#ifdef uos + QFont font("Noto Sans CJK SC,9,-1,5,50,0,0,0,0,0,Regular", 9); + QApplication::setFont(font); +#endif +#ifdef Q_OS_MAC + //这里的字体大小,务必要和查找结果框的高度匹配,否则会结构字体拥挤 + QFont font("Courier New,11,-1,5,50,0,0,0,0,0,Regular", 11); + // qDebug() << "font name mac"; + QApplication::setFont(font); + // qDebug() << QApplication::font().toString(); +#endif + #ifdef Q_OS_WIN QSharedMemory shared("ccnotepad"); if (arguments.size() > 2) @@ -298,15 +310,6 @@ drop_old: pMainNotepad->syncCurSkinToMenu(id); -#ifdef uos - QFont font("Noto Sans CJK JP,9,-1,5,50,0,0,0,0,0,Regular", 9); - QApplication::setFont(font); -#endif -#ifdef Q_OS_MAC - //这里的字体大小,务必要和查找结果框的高度匹配,否则会结构字体拥挤 - QFont font("Courier New,11,-1,5,50,0,0,0,0,0,Regular", 11); - QApplication::setFont(font); -#endif #ifdef Q_OS_WIN //HWND hwnd = ::FindWindowA("Qt5QWindowIcon", "CCNotebook"); @@ -335,7 +338,7 @@ drop_old: #ifdef Q_OS_WIN if (!s_isAdminAuth) { - if (0 == pMainNotepad->restoreLastFiles()) + if (0 == pMainNotepad->restoreLastFiles() && (arguments.size() == 1)) { pMainNotepad->initTabNewOne(); } diff --git a/src/nddsetting.cpp b/src/nddsetting.cpp index 1383333..ed20f73 100755 --- a/src/nddsetting.cpp +++ b/src/nddsetting.cpp @@ -64,8 +64,8 @@ void NddSetting::init() //tabijȣĬΪ4 addKeyValueToNumSets("tablens", 4); - //space replace tabո滻tabĬ1Ϊtrue,0Ϊfalse - addKeyValueToNumSets("tabnouse", 1); + //space replace tabո滻tabĬ0, 1Ϊtrue,0Ϊfalse + addKeyValueToNumSets("tabnouse", 0); addKeyValueToSets("mac", "0"); addKeyValueToNumSets("padtimes", 0); @@ -100,6 +100,21 @@ void NddSetting::init() //0 24 1 36 2 48 addKeyValueToNumSets(ICON_SIZE, 1); + + addKeyValueToNumSets(ZOOMVALUE, 100); + + addKeyValueToNumSets(FINDRESULTPOS, Qt::BottomDockWidgetArea); + + addKeyValueToNumSets(FILELISTPOS, Qt::LeftDockWidgetArea); + + //Ĭ0ʾ + addKeyValueToNumSets(FILELISTSHOW, 0); + + //Ĭʾ + addKeyValueToNumSets(TOOLBARSHOW, 1); + + //ҳĬϲѡԴķѶ + addKeyValueToNumSets(SHOWWEBADDR, 0); }; if (!s_nddSet->contains(VERSION)) @@ -188,6 +203,23 @@ void NddSetting::init() QVariant v(Qt::BottomDockWidgetArea); checkNoExistAdd(FINDRESULTPOS, v); } + + { + QVariant v(Qt::LeftDockWidgetArea); + checkNoExistAdd(FILELISTPOS, v); + } + { + QVariant v(0); + checkNoExistAdd(FILELISTSHOW, v); + } + { + QVariant v(1); + checkNoExistAdd(TOOLBARSHOW, v); + } + { + QVariant v(0); + checkNoExistAdd(SHOWWEBADDR, v); + } } while (false); } @@ -197,6 +229,7 @@ void NddSetting::init() } + //дһܵĻȡõĽӿڣԺÿֶζҪдһдӿ QString NddSetting::getKeyValueFromSets(QString key) { diff --git a/src/nddsetting.h b/src/nddsetting.h index e322f85..25bf155 100755 --- a/src/nddsetting.h +++ b/src/nddsetting.h @@ -18,6 +18,11 @@ static QString ICON_SIZE = "iconsize";//ͼ static QString ZOOMVALUE = "zoom"; //Ŵ static QString VERSION = "version";//ǰ汾 static QString FINDRESULTPOS = "findpos";//Ҵλ +static QString FILELISTPOS = "filepos";//ļбλ +static QString FILELISTSHOW = "showfilelist"; //ļбǷʾ +static QString TOOLBARSHOW = "showbar"; //Ƿʾ +static QString FINDWINSIZE = "findwinsize";//ҿĴС150%Ŵʱáÿֶ +static QString SHOWWEBADDR = "showweb";//webַ˫ҳ class NddSetting { diff --git a/src/plugin.cpp b/src/plugin.cpp new file mode 100755 index 0000000..4427e29 --- /dev/null +++ b/src/plugin.cpp @@ -0,0 +1,70 @@ +#include "plugin.h" +#include +#include +#include +#include + + +bool loadApplication(const QString& strFileName, NDD_PROC_DATA* pProcData) +{ + QLibrary lib(strFileName); + NDD_PROC_IDENTIFY_CALLBACK procCallBack; + + procCallBack = (NDD_PROC_IDENTIFY_CALLBACK)lib.resolve("NDD_PROC_IDENTIFY"); + + if (procCallBack == NULL) + { + return false; + } + + if (!procCallBack(pProcData)) + { + return false; + } + pProcData->m_strFilePath = strFileName; + return true; +} + + + + +int loadProc(const QString& strDirOut, std::function funcallback, QMenu* pUserData) +{ + int nReturn = 0; + QStringList list; + + QDir dir; + dir.setPath(strDirOut); + + QString strDir, strName; + QStringList strFilter; + + strDir = dir.absolutePath(); + strDir += QDir::separator(); +#if defined(Q_OS_WIN) + strFilter << "*.dll"; +#else + strFilter << "lib*.so"; +#endif + list = dir.entryList(strFilter, QDir::Files | QDir::Readable, QDir::Name); + QStringList::Iterator it = list.begin(); + + for (; it != list.end(); ++it) + { + NDD_PROC_DATA procData; + strName = *it; + strName = strDir + strName; + + if (!loadApplication(strName, &procData)) + { + continue; + } + + funcallback(procData, pUserData); + + nReturn++; + } + + return nReturn; +} + diff --git a/src/plugin.h b/src/plugin.h new file mode 100755 index 0000000..918f293 --- /dev/null +++ b/src/plugin.h @@ -0,0 +1,10 @@ +#pragma once +#include "pluginGl.h" +#include +class QMenu; +class QsciScintilla; +class QWidget; + +typedef int (*NDD_PROC_MAIN_CALLBACK)(QWidget* parent, const QString& strFileName, std::functiongetCurEdit); + +int loadProc(const QString& strDirOut, std::function funcallback, QMenu* pUserData); diff --git a/src/plugin/helloworld/helloworld.pro b/src/plugin/helloworld/helloworld.pro new file mode 100755 index 0000000..7a5abfa --- /dev/null +++ b/src/plugin/helloworld/helloworld.pro @@ -0,0 +1,34 @@ +TEMPLATE = lib +LANGUAGE = C++ + +CONFIG += qt warn_on Release +QT += core gui widgets + +HEADERS += *.h +SOURCES += *.cpp +FORMS += *.ui + +INCLUDEPATH += ../../include +INCLUDEPATH += ../../qscint/src +INCLUDEPATH += ../../qscint/src/Qsci + + +win32 { + if(contains(QMAKE_HOST.arch, x86_64)){ + CONFIG(Debug, Debug|Release){ + DESTDIR = ../../x64/Debug/plugin + LIBS += -L../../x64/Debug + LIBS += -lqmyedit_qt5d + }else{ + DESTDIR = ../../x64/Release/plugin + LIBS += -L../../x64/Release + LIBS += -lqmyedit_qt5 + } + } +} + +unix { + UI_DIR = .ui + MOC_DIR = .moc + OBJECTS_DIR = .obj +} diff --git a/src/plugin/helloworld/helloworld.vcxproj.filters b/src/plugin/helloworld/helloworld.vcxproj.filters new file mode 100755 index 0000000..820a103 --- /dev/null +++ b/src/plugin/helloworld/helloworld.vcxproj.filters @@ -0,0 +1,69 @@ + + + + + {99349809-55BA-4b9d-BF79-8FDBB0286EB3} + ui + false + + + {99349809-55BA-4b9d-BF79-8FDBB0286EB3} + ui + false + + + {71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11} + cpp;c;cxx;moc;h;def;odl;idl;res; + + + {71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11} + cpp;c;cxx;moc;h;def;odl;idl;res; + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + Source Files + + + + + Header Files + + + + + + Generated Files + + + Generated Files + + + + + + + + Form Files + + + \ No newline at end of file diff --git a/src/plugin/helloworld/helloworld.vcxproj.user b/src/plugin/helloworld/helloworld.vcxproj.user new file mode 100755 index 0000000..b7a75e9 --- /dev/null +++ b/src/plugin/helloworld/helloworld.vcxproj.user @@ -0,0 +1,10 @@ + + + + + 2023-01-06T12:23:11.3148927Z + + + 2023-01-06T12:23:11.4036545Z + + \ No newline at end of file diff --git a/src/plugin/helloworld/helloworldexport.cpp b/src/plugin/helloworld/helloworldexport.cpp new file mode 100755 index 0000000..84c3f49 --- /dev/null +++ b/src/plugin/helloworld/helloworldexport.cpp @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include +#include "qttestclass.h" + +#define NDD_EXPORTDLL + +#if defined(Q_OS_WIN) +#if defined(NDD_EXPORTDLL) +#define NDD_EXPORT __declspec(dllexport) +#else +#define NDD_EXPORT __declspec(dllimport) +#endif +#endif + +#ifdef __cplusplus + extern "C" { +#endif + + NDD_EXPORT bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData); + NDD_EXPORT int NDD_PROC_MAIN(QWidget* pNotepad, const QString& strFileName, std::functiongetCurEdit); + + +#ifdef __cplusplus + } +#endif + +bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData) +{ + if(pProcData == NULL) + { + return false; + } + pProcData->m_strPlugName = QObject::tr("Hello World Plug"); + pProcData->m_strComment = QObject::tr("char to Upper."); + + pProcData->m_version = QString("v1.0"); + pProcData->m_auther = QString("zuowei.yin"); + return true; +} + +//插件的入口点函数 +int NDD_PROC_MAIN(QWidget* pNotepad, const QString &strFileName, std::functiongetCurEdit) +{ + QsciScintilla* pEdit = getCurEdit(); + + //做一个简单的转大写的操作 + QtTestClass* p = new QtTestClass(pNotepad,pEdit); + //主窗口关闭时,子窗口也关闭。避免空指针操作 + p->setWindowFlag(Qt::Window); + p->show(); + + return 0; +} diff --git a/src/plugin/helloworld/qttestclass.cpp b/src/plugin/helloworld/qttestclass.cpp new file mode 100755 index 0000000..f602623 --- /dev/null +++ b/src/plugin/helloworld/qttestclass.cpp @@ -0,0 +1,30 @@ +#include "qttestclass.h" +#include + +QtTestClass::QtTestClass(QWidget *parent, QsciScintilla* pEdit) + : QWidget(parent) +{ + ui.setupUi(this); + m_pEdit = pEdit; +} + +QtTestClass::~QtTestClass() +{} + +void QtTestClass::on_upper() +{ + QString text = m_pEdit->text(); + + text = text.toUpper(); + + m_pEdit->setText(text); +} + +void QtTestClass::on_lower() +{ + QString text = m_pEdit->text(); + + text = text.toLower(); + + m_pEdit->setText(text); +} \ No newline at end of file diff --git a/src/plugin/helloworld/qttestclass.h b/src/plugin/helloworld/qttestclass.h new file mode 100755 index 0000000..f1e921e --- /dev/null +++ b/src/plugin/helloworld/qttestclass.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include "ui_qttestclass.h" + +class QsciScintilla; +class QtTestClass : public QWidget +{ + Q_OBJECT + +public: + QtTestClass(QWidget *parent, QsciScintilla* pEdit); + ~QtTestClass(); + +private slots: + void on_upper(); + void on_lower(); +private: + Ui::QtTestClassClass ui; + QsciScintilla* m_pEdit; +}; diff --git a/src/plugin/helloworld/qttestclass.ui b/src/plugin/helloworld/qttestclass.ui new file mode 100755 index 0000000..b1527df --- /dev/null +++ b/src/plugin/helloworld/qttestclass.ui @@ -0,0 +1,108 @@ + + + QtTestClassClass + + + + 0 + 0 + 544 + 251 + + + + QtTestClass + + + + + + 这是一个插件例子,把当前文档全部变成大写字母。 +请给我们提交插件! + + + + + + + + + TransUpper + + + + + + + TransLower + + + + + + + Close + + + + + + + + + + + + pushButton_2 + clicked() + QtTestClassClass + close() + + + 435 + 188 + + + 446 + 246 + + + + + upperBt + clicked() + QtTestClassClass + on_upper() + + + 177 + 181 + + + 187 + 247 + + + + + lowerBt + clicked() + QtTestClassClass + on_lower() + + + 296 + 182 + + + 323 + 244 + + + + + + on_upper() + on_lower() + + diff --git a/src/plugin/test/test.cpp b/src/plugin/test/test.cpp new file mode 100755 index 0000000..bd11bb4 --- /dev/null +++ b/src/plugin/test/test.cpp @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include + +#define NDD_EXPORTDLL + +#if defined(Q_OS_WIN) +#if defined(NDD_EXPORTDLL) +#define NDD_EXPORT __declspec(dllexport) +#else +#define NDD_EXPORT __declspec(dllimport) +#endif +#endif + +#ifdef __cplusplus + extern "C" { +#endif + + NDD_EXPORT bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData); + NDD_EXPORT int NDD_PROC_MAIN(QWidget* parent, const QString& strFileName, std::functiongetCurEdit); + + +#ifdef __cplusplus + } +#endif + +bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData) +{ + if(pProcData == NULL) + { + return false; + } + pProcData->m_strPlugName = QObject::tr("Test Plug"); + pProcData->m_strComment = QObject::tr("char to lower."); + + pProcData->m_version = QString("v1.0"); + pProcData->m_auther = QString("zuowei.yin"); + return true; +} + +//插件的入口点函数 +int NDD_PROC_MAIN(QWidget* parent, const QString &strFileName, std::functiongetCurEdit) +{ + QsciScintilla* pEidt = getCurEdit(); + + QString text = pEidt->text(); + + //做一个简单的转大写的操作 + + text = text.toLower(); + + pEidt->setText(text); + + return 0; +} diff --git a/src/plugin/test/test.pro b/src/plugin/test/test.pro new file mode 100755 index 0000000..4a8ea94 --- /dev/null +++ b/src/plugin/test/test.pro @@ -0,0 +1,34 @@ +TEMPLATE = lib +LANGUAGE = C++ + +CONFIG += qt warn_on Debug +QT += core gui widgets + +HEADERS += *.h +SOURCES += *.cpp +FORMS += *.ui + +INCLUDEPATH += ../../include +INCLUDEPATH += ../../qscint/src +INCLUDEPATH += ../../qscint/src/Qsci + + +win32 { + if(contains(QMAKE_HOST.arch, x86_64)){ + CONFIG(Debug, Debug|Release){ + DESTDIR = ../../x64/Debug/Plugin + LIBS += -L../../x64/Debug + LIBS += -lqmyedit_qt5d + }else{ + DESTDIR = ../../x64/Release/Plugin + LIBS += -L../../x64/Release + LIBS += -lqmyedit_qt5 + } + } +} + +unix { + UI_DIR = .ui + MOC_DIR = .moc + OBJECTS_DIR = .obj +} diff --git a/src/pluginGl.h b/src/pluginGl.h new file mode 100755 index 0000000..41971cc --- /dev/null +++ b/src/pluginGl.h @@ -0,0 +1,18 @@ +#pragma once +#include + +struct ndd_proc_data +{ + QString m_strPlugName; // ѡ + QString m_strFilePath; //lib ȫ·ѡ + QString m_strComment; //˵ + QString m_version; //汾롣ѡ + QString m_auther;//ơѡ +}; + +//#define NDD_PROC_IDENTIFY ("nddProc") + +typedef struct ndd_proc_data NDD_PROC_DATA; + +typedef bool (*NDD_PROC_IDENTIFY_CALLBACK)(NDD_PROC_DATA* pProcData); +typedef void (*NDD_PROC_FOUND_CALLBACK)(NDD_PROC_DATA* pProcData, void* pUserData); \ No newline at end of file diff --git a/src/pluginmgr.cpp b/src/pluginmgr.cpp new file mode 100755 index 0000000..6ba10e1 --- /dev/null +++ b/src/pluginmgr.cpp @@ -0,0 +1,41 @@ +#include "pluginmgr.h" +#include "rcglobal.h" + + +PluginMgr::PluginMgr(QWidget *parent, QList& pluginList) + : QMainWindow(parent) +{ + ui.setupUi(this); + + init(pluginList); +} + +PluginMgr::~PluginMgr() +{} + +void PluginMgr::init(QList& pluginList) +{ + ui.pluginTable->clearContents(); + ui.pluginTable->setRowCount(0); + + for (int i = 0; i < pluginList.size(); ++i) + { + ui.pluginTable->insertRow(i); + + NDD_PROC_DATA v = pluginList.at(i); + + ui.pluginTable->setItem(i, 0, new QTableWidgetItem(v.m_strPlugName)); + ui.pluginTable->setItem(i, 1, new QTableWidgetItem(v.m_version)); + ui.pluginTable->setItem(i, 2, new QTableWidgetItem(v.m_auther)); + ui.pluginTable->setItem(i, 3, new QTableWidgetItem(v.m_strComment)); + ui.pluginTable->setItem(i, 4, new QTableWidgetItem(v.m_strFilePath)); + } +} + +void PluginMgr::slot_openPluginDir() +{ + QString strDir = qApp->applicationDirPath(); + QString path = QString("%1/plugin").arg(strDir); + + showFileInExplorer(path); +} diff --git a/src/pluginmgr.h b/src/pluginmgr.h new file mode 100755 index 0000000..996d333 --- /dev/null +++ b/src/pluginmgr.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include "ui_pluginmgr.h" +#include "pluginGl.h" + +class PluginMgr : public QMainWindow +{ + Q_OBJECT + +public: + PluginMgr(QWidget *parent, QList& pluginList); + ~PluginMgr(); + +private: + void init(QList& pluginList); + +private slots: + void slot_openPluginDir(); + +private: + Ui::PluginMgrClass ui; +}; diff --git a/src/pluginmgr.ui b/src/pluginmgr.ui new file mode 100755 index 0000000..27dd173 --- /dev/null +++ b/src/pluginmgr.ui @@ -0,0 +1,161 @@ + + + PluginMgrClass + + + + 0 + 0 + 974 + 488 + + + + PluginMgr + + + + + 3 + + + 3 + + + 3 + + + + + + Name + + + + + Version + + + + + Auther + + + + + Comment + + + + + Path + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Plugin Dir + + + + + + + Close + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 0 + 0 + 974 + 23 + + + + + + TopToolBarArea + + + false + + + + + + + + + cancelBt + clicked() + PluginMgrClass + close() + + + 539 + 449 + + + 637 + 461 + + + + + pluginDirBt + clicked() + PluginMgrClass + slot_openPluginDir() + + + 453 + 453 + + + 463 + 490 + + + + + + slot_openPluginDir() + + diff --git a/src/qscidisplaywindow.cpp b/src/qscidisplaywindow.cpp index 5baf23b..5240d46 100755 --- a/src/qscidisplaywindow.cpp +++ b/src/qscidisplaywindow.cpp @@ -3,6 +3,7 @@ #include "textfind.h" #include "common.h" #include "styleset.h" +#include "rcglobal.h" #include #include @@ -538,15 +539,6 @@ void QsciDisplayWindow::slot_FindTextWithPara(int prevOrNext, QString text) //定位到文件夹 void QsciDisplayWindow::slot_showFileInExplorer() { - QString path, cmd; -#ifdef _WIN32 - path = m_filePath.replace("/", "\\"); - cmd = QString("explorer.exe /select,%1").arg(path); -#else - path = m_filePath.replace("\\", "/"); - cmd = QString("open -R %1").arg(path); -#endif - QProcess process; - process.startDetached(cmd); + showFileInExplorer(m_filePath); } diff --git a/src/qscint/scintilla/include/Scintilla.h b/src/qscint/scintilla/include/Scintilla.h index 2847e1e..eff3878 100755 --- a/src/qscint/scintilla/include/Scintilla.h +++ b/src/qscint/scintilla/include/Scintilla.h @@ -1,4 +1,4 @@ -/* Scintilla source code edit control */ +/* Scintilla source code edit control */ /** @file Scintilla.h ** Interface to the edit control. **/ @@ -1101,7 +1101,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCN_URIDROPPED 2015 #define SCN_DWELLSTART 2016 #define SCN_DWELLEND 2017 -#define SCN_ZOOM 2018 +#define SCN_ZOOM_CODE 2018 #define SCN_HOTSPOTCLICK 2019 #define SCN_HOTSPOTDOUBLECLICK 2020 #define SCN_CALLTIPCLICK 2021 diff --git a/src/qscint/scintilla/src/Editor.cpp b/src/qscint/scintilla/src/Editor.cpp index 3a9da95..0174286 100755 --- a/src/qscint/scintilla/src/Editor.cpp +++ b/src/qscint/scintilla/src/Editor.cpp @@ -2488,7 +2488,7 @@ void Editor::NotifyDwelling(Point pt, bool state) { void Editor::NotifyZoom() { SCNotification scn = {}; - scn.nmhdr.code = SCN_ZOOM; + scn.nmhdr.code = SCN_ZOOM_CODE; NotifyParent(scn); } diff --git a/src/qscint/src/Qsci/qsciglobal.h b/src/qscint/src/Qsci/qsciglobal.h index 86c9939..61e48d5 100755 --- a/src/qscint/src/Qsci/qsciglobal.h +++ b/src/qscint/src/Qsci/qsciglobal.h @@ -37,6 +37,7 @@ // Define QSCINTILLA_MAKE_DLL to create a QScintilla shared library, or // define QSCINTILLA_DLL to link against a QScintilla shared library, or define // neither to either build or link against a static QScintilla library. + #if defined(QSCINTILLA_DLL) #define QSCINTILLA_EXPORT Q_DECL_IMPORT #elif defined(QSCINTILLA_MAKE_DLL) diff --git a/src/qscint/src/Qsci/qscilexer.h b/src/qscint/src/Qsci/qscilexer.h index 0afc1f8..862f818 100755 --- a/src/qscint/src/Qsci/qscilexer.h +++ b/src/qscint/src/Qsci/qscilexer.h @@ -302,9 +302,21 @@ public: const char *prefix = "/Scintilla") const; StyleData &styleData(int style) const; + StyleData& setThemesDefaultStyleData(int style) const; void resetStyleDefaults(); + QByteArray getCommentLineSymbol(); + void setCommentLineSymbol(QByteArray comment); + + QByteArray getCommentStart(); + QByteArray getCommentEnd(); + + void setCommentStart(QByteArray commentStart); + void setCommentEnd(QByteArray commentEnd); + + static void setCurThemes(int themesId); + public slots: //! The auto-indentation style is set to \a autoindentstyle. //! @@ -365,6 +377,14 @@ protected: bool m_isUserDefineKeyword; //是否使用用户自定义关键字。默认false QByteArray m_userDefineKeyword;//用户自定义的关键字 + + QByteArray m_commentSymbol; + QByteArray m_commentStart; + QByteArray m_commentEnd; + + //当前主题id + static int m_themesId; + private: diff --git a/src/qscint/src/Qsci/qscilexerglobal.h b/src/qscint/src/Qsci/qscilexerglobal.h index 9d65bde..1d16681 100755 --- a/src/qscint/src/Qsci/qscilexerglobal.h +++ b/src/qscint/src/Qsci/qscilexerglobal.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include #include #include @@ -7,6 +7,47 @@ class QsciScintilla; class QsciStyle; +enum GLOBAL_STYLES { + GLOBAL_OVERRIDE=0, + DEFAULT_STYLE, + INDENT_GUIDELINE, + BRACE_HIGHIGHT, + BAD_BRACE_COLOUR, + CURRENT_LINE_BACKGROUND_COLOR, + SELECT_TEXT_COLOR, + CARET_COLOUR, + EDGE_COLOUR, + LINE_NUMBER_MARGIN, + BOOKMARK_MARGIN, + FOLD, + FOLD_ACTIVE, + FOLD_MARGIN, + WHITE_SPACE_SYMBOL, + SMART_HIGHLIGHTING, + FIND_MARK_STYLE, + MARK_STYLE_1, + MARK_STYLE_2, + MARK_STYLE_3, + MARK_STYLE_4, + MARK_STYLE_5, + INCREMENTAL_HIGHLIGHT, + TAGS_MATCH_HIGHLIGHT, + TAGS_ATTRIBUTE, + //ACTIVE_TAB_FOCUSED, + //ACTIVE_TAB_UNFOCUSED, + //ACTIVE_TAB_TEXT, + //INACTIVE_TABS, + URL_HOVERRED, +}; + +enum CHANGE_OPER_BIT { + FG_BIT = 0x1, + BG_BIT = 0x2, + FONT_BIT = 0x4, + SIZE_BIT = 0x8, + ALL_OPER_BIT = 0xf, +}; + class QSCINTILLA_EXPORT QsciLexerGlobal : public QsciLexer { Q_OBJECT @@ -19,4 +60,10 @@ public: const char* language() const; QString description(int style) const; QFont defaultFont(int style) const; + virtual QColor defaultColor(int style) const; + virtual QColor defaultPaper(int style) const; + + int changeOperBit(int style) const; + + static int getRealStyleId(int style); }; diff --git a/src/qscint/src/Qsci/qsciscintilla.h b/src/qscint/src/Qsci/qsciscintilla.h index e831b0f..1420d7e 100755 --- a/src/qscint/src/Qsci/qsciscintilla.h +++ b/src/qscint/src/Qsci/qsciscintilla.h @@ -72,10 +72,10 @@ struct FindState bool show; }; -enum FindNextType { - FINDNEXTTYPE_FINDNEXT, - FINDNEXTTYPE_REPLACENEXT, - FINDNEXTTYPE_FINDNEXTFORREPLACE +enum FindNextType { + FINDNEXTTYPE_FINDNEXT, + FINDNEXTTYPE_REPLACENEXT, + FINDNEXTTYPE_FINDNEXTFORREPLACE }; //! \brief The QsciScintilla class implements a higher level, more Qt-like, @@ -1670,6 +1670,8 @@ public: void setHtmlHighLightTag(bool v); bool getHtmlHighLightTag(); + /* virtual void adjuctSkinStyle() {}*/ + public slots: //! Appends the text \a text to the end of the text edit. Note that the //! undo/redo history is cleared by this function. @@ -2214,6 +2216,10 @@ protected: //! \reimp virtual void wheelEvent(QWheelEvent *e); + virtual void addHotSpot() {} + + void setStylesFont(const QFont& f, int style); + private slots: void handleCallTipClick(int dir); void handleCharAdded(int charadded); @@ -2225,6 +2231,7 @@ private slots: int added, int line, int foldNow, int foldPrev, int token, int annotationLinesAdded); void handlePropertyChange(const char *prop, const char *val); + void handleSavePointReached(); void handleSavePointLeft(); void handleSelectionChanged(bool yes); @@ -2271,7 +2278,7 @@ private: int visLevels = 0, int level = -1); void setFoldMarker(int marknr, int mark = SC_MARK_EMPTY); void setLexerStyle(int style); - void setStylesFont(const QFont &f, int style); + void setEnabledColors(int style, QColor &fore, QColor &back); void braceMatch(); diff --git a/src/qscint/src/qscilexer.cpp b/src/qscint/src/qscilexer.cpp index 0473b02..b49fdc5 100755 --- a/src/qscint/src/qscilexer.cpp +++ b/src/qscint/src/qscilexer.cpp @@ -1,793 +1,889 @@ -// This module implements the QsciLexer class. -// -// Copyright (c) 2021 Riverbank Computing Limited -// -// This file is part of QScintilla. -// -// This file may be used under the terms of the GNU General Public License -// version 3.0 as published by the Free Software Foundation and appearing in -// the file LICENSE included in the packaging of this file. Please review the -// following information to ensure the GNU General Public License version 3.0 -// requirements will be met: http://www.gnu.org/copyleft/gpl.html. -// -// If you do not wish to use this file under the terms of the GPL version 3.0 -// then you may purchase a commercial license. For more information contact -// info@riverbankcomputing.com. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - - -#include "Qsci/qscilexer.h" - -#include -#include -#include -#include - -#include "Qsci/qsciapis.h" -#include "Qsci/qsciscintilla.h" -#include "Qsci/qsciscintillabase.h" - -int QsciLexer::s_defaultFontSize = 14; - +// This module implements the QsciLexer class. +// +// Copyright (c) 2021 Riverbank Computing Limited +// +// This file is part of QScintilla. +// +// This file may be used under the terms of the GNU General Public License +// version 3.0 as published by the Free Software Foundation and appearing in +// the file LICENSE included in the packaging of this file. Please review the +// following information to ensure the GNU General Public License version 3.0 +// requirements will be met: http://www.gnu.org/copyleft/gpl.html. +// +// If you do not wish to use this file under the terms of the GPL version 3.0 +// then you may purchase a commercial license. For more information contact +// info@riverbankcomputing.com. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + + +#include "Qsci/qscilexer.h" + +#include +#include +#include +#include + +#include "Qsci/qsciapis.h" +#include "Qsci/qsciscintilla.h" +#include "Qsci/qsciscintillabase.h" + +int QsciLexer::s_defaultFontSize = 14; + +int QsciLexer::m_themesId = 0; + #if defined(Q_OS_WIN) QFont QsciLexer::s_defaultLangFont("Courier New", QsciLexer::s_defaultFontSize); #elif defined(Q_OS_MAC) QFont QsciLexer::s_defaultLangFont("Menlo", s_defaultFontSize); #else QFont QsciLexer::s_defaultLangFont("Courier 10 Pitch", 14); -#endif - -// The ctor. -QsciLexer::QsciLexer(QObject *parent) - : QObject(parent), - autoIndStyle(-1), apiSet(0), attached_editor(0), m_lexerId(QsciScintillaBase::SCLEX_CONTAINER), m_isUserDefineKeyword(false) -{ -#if 0 -#if defined(Q_OS_WIN) - defFont = QFont("Courier New", s_defaultFontSize); -#elif defined(Q_OS_MAC) - defFont = QFont("Menlo", s_defaultFontSize); -#else - defFont = QFont("Bitstream Vera Sans", 9); -#endif -#endif - defFont = s_defaultLangFont; - - // Set the default fore and background colours. - QPalette pal = QApplication::palette(); - //defColor = pal.text().color(); - defColor = QColor(Qt::black); - defPaper = pal.base().color(); - - // Putting this on the heap means we can keep the style getters const. - style_map = new StyleDataMap; - style_map->style_data_set = false; -} - - -// The dtor. -QsciLexer::~QsciLexer() -{ - delete style_map; -} - +#endif + +// The ctor. +QsciLexer::QsciLexer(QObject *parent) + : QObject(parent), + autoIndStyle(-1), apiSet(0), attached_editor(0), m_lexerId(QsciScintillaBase::SCLEX_CONTAINER), m_isUserDefineKeyword(false) +{ +#if 0 +#if defined(Q_OS_WIN) + defFont = QFont("Courier New", s_defaultFontSize); +#elif defined(Q_OS_MAC) + defFont = QFont("Menlo", s_defaultFontSize); +#else + defFont = QFont("Bitstream Vera Sans", 9); +#endif +#endif + defFont = s_defaultLangFont; + + // Set the default fore and background colours. + QPalette pal = QApplication::palette(); + //defColor = pal.text().color(); + defColor = QColor(Qt::black); + defPaper = pal.base().color(); + + // Putting this on the heap means we can keep the style getters const. + style_map = new StyleDataMap; + style_map->style_data_set = false; +} + + +// The dtor. +QsciLexer::~QsciLexer() +{ + delete style_map; +} + void QsciLexer::setProLangeDefaultFont(const QFont & font) { s_defaultLangFont = font; } - - -// Set the attached editor. -void QsciLexer::setEditor(QsciScintilla *editor) -{ - attached_editor = editor; -} - - -// Return the lexer name. -const char *QsciLexer::lexer() const -{ - return 0; -} - -void QsciLexer::setLexerTag(QString tag) -{ - m_tagName = tag; -} - -QString QsciLexer::lexerTag() -{ - if (m_tagName.isEmpty()) - { - return QString(lexer()); - } - return m_tagName; -} - - -// Return the lexer identifier. -int QsciLexer::lexerId() const -{ - return m_lexerId; -} - -void QsciLexer::setLexerId(int id) -{ - m_lexerId = id; -} - - -// Return the number of style bits needed by the lexer. -int QsciLexer::styleBitsNeeded() const -{ - return 8; -} - - -// Make sure the style defaults have been set. -void QsciLexer::setStyleDefaults() const -{ - if (!style_map->style_data_set) - { - for (int i = 0; i <= QsciScintillaBase::STYLE_MAX; ++i) - if (!description(i).isEmpty()) - styleData(i); - - style_map->style_data_set = true; - } -} - -//恢复到默认lexer状态 -void QsciLexer::resetStyleDefaults() -{ - style_map->style_data_set = false; - style_map->style_data.clear(); - setStyleDefaults(); -} - - -// Return a reference to a style's data, setting up the defaults if needed. -QsciLexer::StyleData &QsciLexer::styleData(int style) const -{ - StyleData &sd = style_map->style_data[style]; - - // See if this is a new style by checking if the colour is valid. - if (!sd.color.isValid()) - { - sd.color = defaultColor(style); - sd.paper = defaultPaper(style); - sd.font = defaultFont(style); - sd.eol_fill = defaultEolFill(style); - } - - return sd; -} - - -// Set the APIs associated with the lexer. -void QsciLexer::setAPIs(QsciAbstractAPIs *apis) -{ - apiSet = apis; -} - - -// Return a pointer to the current APIs if there are any. -QsciAbstractAPIs *QsciLexer::apis() const -{ - return apiSet; -} - - -// Default implementation to return the set of fill up characters that can end -// auto-completion. -const char *QsciLexer::autoCompletionFillups() const -{ - return "("; -} - - -// Default implementation to return the view used for indentation guides. -int QsciLexer::indentationGuideView() const -{ - return QsciScintillaBase::SC_IV_LOOKBOTH; -} - - -// Default implementation to return the list of character sequences that can -// separate auto-completion words. -QStringList QsciLexer::autoCompletionWordSeparators() const -{ - return QStringList(); -} - - -// Default implementation to return the list of keywords that can start a -// block. -const char *QsciLexer::blockStartKeyword(int *) const -{ - return 0; -} - - -// Default implementation to return the list of characters that can start a -// block. -const char *QsciLexer::blockStart(int *) const -{ - return 0; -} - - -// Default implementation to return the list of characters that can end a -// block. -const char *QsciLexer::blockEnd(int *) const -{ - return 0; -} - - -// Default implementation to return the style used for braces. -int QsciLexer::braceStyle() const -{ - return -1; -} - - -// Default implementation to return the number of lines to look back when -// auto-indenting. -int QsciLexer::blockLookback() const -{ - return 20; -} - - -// Default implementation to return the case sensitivity of the language. -bool QsciLexer::caseSensitive() const -{ - return true; -} - - -// Default implementation to return the characters that make up a word. -const char *QsciLexer::wordCharacters() const -{ - return 0; -} - - -// Default implementation to return the style used for whitespace. -int QsciLexer::defaultStyle() const -{ - return 0; -} - - -// Returns the foreground colour of the text for a style. -QColor QsciLexer::color(int style) const -{ - return styleData(style).color; -} - - -// Returns the background colour of the text for a style. -QColor QsciLexer::paper(int style) const -{ - return styleData(style).paper; -} - - -// Returns the font for a style. -QFont QsciLexer::font(int style) const -{ - return styleData(style).font; -} - - -// Returns the end-of-line fill for a style. -bool QsciLexer::eolFill(int style) const -{ - return styleData(style).eol_fill; -} - - -// Returns the set of keywords. -const char *QsciLexer::keywords(int) -{ - if (m_isUserDefineKeyword) - { - //如果是自定义用户关键字,则根据语言tag获取 - return getUserDefineKeywords(); - } - - return 0; -} - - -// Returns the default EOL fill for a style. -bool QsciLexer::defaultEolFill(int) const -{ - return false; -} - - -// Returns the default font for a style. -QFont QsciLexer::defaultFont(int) const -{ - return defaultFont(); -} - - -// Returns the default font. -QFont QsciLexer::defaultFont() const -{ - return defFont; -} - - -// Sets the default font. -void QsciLexer::setDefaultFont(const QFont &f) -{ - defFont = f; -} - - -// Returns the default text colour for a style. -QColor QsciLexer::defaultColor(int) const -{ - return defaultColor(); -} - - -// Returns the default text colour. -QColor QsciLexer::defaultColor() const -{ - return defColor; -} - - -// Sets the default text colour. -void QsciLexer::setDefaultColor(const QColor &c) -{ - defColor = c; -} - - -// Returns the default paper colour for a styles. -QColor QsciLexer::defaultPaper(int) const -{ - return defaultPaper(); -} - - -// Returns the default paper colour. -QColor QsciLexer::defaultPaper() const -{ - return defPaper; -} - - -// Sets the default paper colour. -void QsciLexer::setDefaultPaper(const QColor &c) -{ - defPaper = c; - - // Normally the default values are only intended to provide defaults when a - // lexer is first setup because once a style has been referenced then a - // copy of the default is made. However the default paper is a special - // case because there is no other way to set the background colour used - // where there is no text. Therefore we also actively set it. - setPaper(c, QsciScintillaBase::STYLE_DEFAULT); -} - - -// Read properties from the settings. -bool QsciLexer::readProperties(QSettings &,const QString &) -{ - return true; -} - - -// Refresh all properties. -void QsciLexer::refreshProperties() -{ -} - - -// Write properties to the settings. -bool QsciLexer::writeProperties(QSettings &,const QString &) const -{ - return true; -} - - -// Restore the user settings. -bool QsciLexer::readSettings(QSettings &qs,const char *prefix) -{ - bool ok, flag, rc = true; - int num; - QString key, full_key; - QStringList fdesc; - - setStyleDefaults(); - - // Read the styles. - for (int i = 0; i <= QsciScintillaBase::STYLE_MAX; ++i) - { - // Ignore invalid styles. - if (description(i).isEmpty()) - continue; - - key = QString("%1/%2/style%3/").arg(prefix).arg(language()).arg(i); - - // Read the foreground colour. - full_key = key + "color"; - - ok = qs.contains(full_key); - num = qs.value(full_key).toInt(); - - if (ok) - setColor(QColor((num >> 16) & 0xff, (num >> 8) & 0xff, num & 0xff), i); - else - rc = false; - - // Read the end-of-line fill. - full_key = key + "eolfill"; - - ok = qs.contains(full_key); - flag = qs.value(full_key, false).toBool(); - - if (ok) - setEolFill(flag, i); - else - rc = false; - - // Read the font. First try the deprecated format that uses an integer - // point size. - full_key = key + "font"; - - ok = qs.contains(full_key); - fdesc = qs.value(full_key).toStringList(); - - if (ok && fdesc.count() == 5) - { - QFont f; - - f.setFamily(fdesc[0]); - f.setPointSize(fdesc[1].toInt()); - f.setBold(fdesc[2].toInt()); - f.setItalic(fdesc[3].toInt()); - f.setUnderline(fdesc[4].toInt()); - - setFont(f, i); - } - else - rc = false; - - // Now try the newer font format that uses a floating point point size. - // It is not an error if it doesn't exist. - full_key = key + "font2"; - - ok = qs.contains(full_key); - fdesc = qs.value(full_key).toStringList(); - - if (ok) - { - // Allow for future versions with more fields. - if (fdesc.count() >= 5) - { - QFont f; - - f.setFamily(fdesc[0]); - f.setPointSizeF(fdesc[1].toDouble()); - f.setBold(fdesc[2].toInt()); - f.setItalic(fdesc[3].toInt()); - f.setUnderline(fdesc[4].toInt()); - - setFont(f, i); - } - else - { - rc = false; - } - } - -#if 1 //不读取背景颜色,和主题保存一致 - // Read the background colour. - full_key = key + "paper"; - - ok = qs.contains(full_key); - num = qs.value(full_key).toInt(); - - if (ok) - setPaper(QColor((num >> 16) & 0xff, (num >> 8) & 0xff, num & 0xff), i); - else - rc = false; -#endif - } - - // Read the properties. - key = QString("%1/%2/properties/").arg(prefix).arg(language()); - - if (!readProperties(qs,key)) - rc = false; - - refreshProperties(); - - // Read the rest. - key = QString("%1/%2/").arg(prefix).arg(language()); - - // Read the default foreground colour. - full_key = key + "defaultcolor"; - - ok = qs.contains(full_key); - num = qs.value(full_key).toInt(); - - if (ok) - setDefaultColor(QColor((num >> 16) & 0xff, (num >> 8) & 0xff, num & 0xff)); - else - rc = false; - -#if 1 - // Read the default background colour. - full_key = key + "defaultpaper"; - - ok = qs.contains(full_key); - num = qs.value(full_key).toInt(); - - if (ok) - setDefaultPaper(QColor((num >> 16) & 0xff, (num >> 8) & 0xff, num & 0xff)); - else - rc = false; -#endif - - // Read the default font. First try the deprecated format that uses an - // integer point size. - full_key = key + "defaultfont"; - - ok = qs.contains(full_key); - fdesc = qs.value(full_key).toStringList(); - - if (ok && fdesc.count() == 5) - { - QFont f; - - f.setFamily(fdesc[0]); - f.setPointSize(fdesc[1].toInt()); - f.setBold(fdesc[2].toInt()); - f.setItalic(fdesc[3].toInt()); - f.setUnderline(fdesc[4].toInt()); - - setDefaultFont(f); - } - else - rc = false; - - // Now try the newer font format that uses a floating point point size. It - // is not an error if it doesn't exist. - full_key = key + "defaultfont2"; - - ok = qs.contains(full_key); - fdesc = qs.value(full_key).toStringList(); - - if (ok) - { - // Allow for future versions with more fields. - if (fdesc.count() >= 5) - { - QFont f; - - f.setFamily(fdesc[0]); - f.setPointSizeF(fdesc[1].toDouble()); - f.setBold(fdesc[2].toInt()); - f.setItalic(fdesc[3].toInt()); - f.setUnderline(fdesc[4].toInt()); - - setDefaultFont(f); - } - else - { - rc = false; - } - } - - full_key = key + "autoindentstyle"; - - ok = qs.contains(full_key); - num = qs.value(full_key).toInt(); - - if (ok) - setAutoIndentStyle(num); - else - rc = false; - - return rc; -} - - -// Save the user settings. -bool QsciLexer::writeSettings(QSettings &qs,const char *prefix) const -{ - bool rc = true; - QString key, fmt("%1"); - int num; - QStringList fdesc; - - setStyleDefaults(); - - // Write the styles. - for (int i = 0; i <= QsciScintillaBase::STYLE_MAX; ++i) - { - // Ignore invalid styles. - if (description(i).isEmpty()) - continue; - - QColor c; - - key = QString("%1/%2/style%3/").arg(prefix).arg(language()).arg(i); - - // Write the foreground colour. - c = color(i); - num = (c.red() << 16) | (c.green() << 8) | c.blue(); - - qs.setValue(key + "color", num); - - // Write the end-of-line fill. - qs.setValue(key + "eolfill", eolFill(i)); - - // Write the font using the deprecated format. - QFont f = font(i); - - fdesc.clear(); - fdesc += f.family(); - fdesc += fmt.arg(f.pointSize()); - - // The casts are for Borland. - fdesc += fmt.arg((int)f.bold()); - fdesc += fmt.arg((int)f.italic()); - fdesc += fmt.arg((int)f.underline()); - - qs.setValue(key + "font", fdesc); - - // Write the font using the newer format. - fdesc[1] = fmt.arg(f.pointSizeF()); - - qs.setValue(key + "font2", fdesc); - -#if 1 //背景颜色和主题皮肤保存一致,故不写入背景颜色 - // Write the background colour. - c = paper(i); - num = (c.red() << 16) | (c.green() << 8) | c.blue(); - - qs.setValue(key + "paper", num); -#endif - } - - // Write the properties. - key = QString("%1/%2/properties/").arg(prefix).arg(language()); - - if (!writeProperties(qs,key)) - rc = false; - - // Write the rest. - key = QString("%1/%2/").arg(prefix).arg(language()); - - // Write the default foreground colour. - num = (defColor.red() << 16) | (defColor.green() << 8) | defColor.blue(); - - qs.setValue(key + "defaultcolor", num); - -#if 1 - // Write the default background colour. - num = (defPaper.red() << 16) | (defPaper.green() << 8) | defPaper.blue(); - - qs.setValue(key + "defaultpaper", num); -#endif - - // Write the default font using the deprecated format. - fdesc.clear(); - fdesc += defFont.family(); - fdesc += fmt.arg(defFont.pointSize()); - - // The casts are for Borland. - fdesc += fmt.arg((int)defFont.bold()); - fdesc += fmt.arg((int)defFont.italic()); - fdesc += fmt.arg((int)defFont.underline()); - - qs.setValue(key + "defaultfont", fdesc); - - // Write the font using the newer format. - fdesc[1] = fmt.arg(defFont.pointSizeF()); - - qs.setValue(key + "defaultfont2", fdesc); - - qs.setValue(key + "autoindentstyle", autoIndStyle); - - return rc; -} - - -// Return the auto-indentation style. -int QsciLexer::autoIndentStyle() -{ - // We can't do this in the ctor because we want the virtuals to work. - if (autoIndStyle < 0) - autoIndStyle = (blockStartKeyword() || blockStart() || blockEnd()) ? - 0 : QsciScintilla::AiMaintain; - - return autoIndStyle; -} - - -// Set the auto-indentation style. -void QsciLexer::setAutoIndentStyle(int autoindentstyle) -{ - autoIndStyle = autoindentstyle; -} - - -// Set the foreground colour for a style. -void QsciLexer::setColor(const QColor &c, int style) -{ - if (style >= 0) - { - styleData(style).color = c; - emit colorChanged(c, style); - } - else - for (int i = 0; i <= QsciScintillaBase::STYLE_MAX; ++i) - if (!description(i).isEmpty()) - setColor(c, i); -} - - -// Set the end-of-line fill for a style. -void QsciLexer::setEolFill(bool eolfill, int style) -{ - if (style >= 0) - { - styleData(style).eol_fill = eolfill; - emit eolFillChanged(eolfill, style); - } - else - for (int i = 0; i <= QsciScintillaBase::STYLE_MAX; ++i) - if (!description(i).isEmpty()) - setEolFill(eolfill, i); -} - - -// Set the font for a style. -void QsciLexer::setFont(const QFont &f, int style) -{ - if (style >= 0) - { - styleData(style).font = f; - emit fontChanged(f, style); - } - else - for (int i = 0; i <= QsciScintillaBase::STYLE_MAX; ++i) - if (!description(i).isEmpty()) - setFont(f, i); -} - - -// Set the background colour for a style. -void QsciLexer::setPaper(const QColor &c, int style) -{ - if (style >= 0) - { - styleData(style).paper = c; - emit paperChanged(c, style); - } - else - { - for (int i = 0; i <= QsciScintillaBase::STYLE_MAX; ++i) - if (!description(i).isEmpty()) - setPaper(c, i); - - emit paperChanged(c, QsciScintillaBase::STYLE_DEFAULT); - } -} + + +// Set the attached editor. +void QsciLexer::setEditor(QsciScintilla *editor) +{ + attached_editor = editor; +} + + +// Return the lexer name. +const char *QsciLexer::lexer() const +{ + return 0; +} + +void QsciLexer::setLexerTag(QString tag) +{ + m_tagName = tag; +} + +QString QsciLexer::lexerTag() +{ + if (m_tagName.isEmpty()) + { + return QString(lexer()); + } + return m_tagName; +} + + +// Return the lexer identifier. +int QsciLexer::lexerId() const +{ + return m_lexerId; +} + +void QsciLexer::setLexerId(int id) +{ + m_lexerId = id; +} + + +// Return the number of style bits needed by the lexer. +int QsciLexer::styleBitsNeeded() const +{ + return 8; +} + + +// Make sure the style defaults have been set. +void QsciLexer::setStyleDefaults() const +{ + if (!style_map->style_data_set) + { + for (int i = 0; i <= QsciScintillaBase::STYLE_MAX; ++i) + { + if (!description(i).isEmpty()) + { + setThemesDefaultStyleData(i); + } + } + + style_map->style_data_set = true; + } +} + +//恢复到默认lexer状态 +void QsciLexer::resetStyleDefaults() +{ + style_map->style_data_set = false; + style_map->style_data.clear(); + setStyleDefaults(); +} + + +// Return a reference to a style's data, setting up the defaults if needed. +QsciLexer::StyleData &QsciLexer::styleData(int style) const +{ + StyleData &sd = style_map->style_data[style]; + + //如果是非默认主题,则无条件的把所有属性都设置为默认值 + //这样一来,默认都是默认风格,只有文件中存在配置值的才是其它指定风格 + + // See if this is a new style by checking if the colour is valid. + if (!sd.color.isValid()) + { + sd.color = defaultColor(style); + sd.paper = defaultPaper(style); + sd.font = defaultFont(style); + sd.eol_fill = defaultEolFill(style); + } + + return sd; +} + +// Return a reference to a style's data, setting up the defaults if needed. +QsciLexer::StyleData& QsciLexer::setThemesDefaultStyleData(int style) const +{ + + StyleData& sd = style_map->style_data[style]; + + //如果是非默认主题,则无条件的把所有属性都设置为默认值 + //这样一来,默认都是GLobal的默认风格,只有文件中存在配置值的才是其它指定风格 + if (L_GLOBAL != lexerId()) + { + // See if this is a new style by checking if the colour is valid. + if (m_themesId != 0 || !sd.color.isValid()) + { + sd.color = defaultColor(); + sd.paper = defaultPaper(); + sd.font = defaultFont(); + sd.eol_fill = defaultEolFill(style); + } + } + else + { + //Global本身是个例外,它不能全部使用默认风格。而是要使用它自定义的风格。 + if (m_themesId != 0 || !sd.color.isValid()) + { + sd.color = defaultColor(style); + sd.paper = defaultPaper(style); + sd.font = defaultFont(style); + sd.eol_fill = defaultEolFill(style); + } + } + + return sd; +} + +// Set the APIs associated with the lexer. +void QsciLexer::setAPIs(QsciAbstractAPIs *apis) +{ + apiSet = apis; +} + + +// Return a pointer to the current APIs if there are any. +QsciAbstractAPIs *QsciLexer::apis() const +{ + return apiSet; +} + + +// Default implementation to return the set of fill up characters that can end +// auto-completion. +const char *QsciLexer::autoCompletionFillups() const +{ + return "("; +} + + +// Default implementation to return the view used for indentation guides. +int QsciLexer::indentationGuideView() const +{ + return QsciScintillaBase::SC_IV_LOOKBOTH; +} + + +// Default implementation to return the list of character sequences that can +// separate auto-completion words. +QStringList QsciLexer::autoCompletionWordSeparators() const +{ + return QStringList(); +} + + +// Default implementation to return the list of keywords that can start a +// block. +const char *QsciLexer::blockStartKeyword(int *) const +{ + return 0; +} + + +// Default implementation to return the list of characters that can start a +// block. +const char *QsciLexer::blockStart(int *) const +{ + return 0; +} + + +// Default implementation to return the list of characters that can end a +// block. +const char *QsciLexer::blockEnd(int *) const +{ + return 0; +} + + +// Default implementation to return the style used for braces. +int QsciLexer::braceStyle() const +{ + return -1; +} + + +// Default implementation to return the number of lines to look back when +// auto-indenting. +int QsciLexer::blockLookback() const +{ + return 20; +} + + +// Default implementation to return the case sensitivity of the language. +bool QsciLexer::caseSensitive() const +{ + return true; +} + + +// Default implementation to return the characters that make up a word. +const char *QsciLexer::wordCharacters() const +{ + return 0; +} + + +// Default implementation to return the style used for whitespace. +int QsciLexer::defaultStyle() const +{ + return 0; +} + + +// Returns the foreground colour of the text for a style. +QColor QsciLexer::color(int style) const +{ + return styleData(style).color; +} + + +// Returns the background colour of the text for a style. +QColor QsciLexer::paper(int style) const +{ + return styleData(style).paper; +} + + +// Returns the font for a style. +QFont QsciLexer::font(int style) const +{ + return styleData(style).font; +} + + +// Returns the end-of-line fill for a style. +bool QsciLexer::eolFill(int style) const +{ + return styleData(style).eol_fill; +} + + +// Returns the set of keywords. +const char *QsciLexer::keywords(int) +{ + if (m_isUserDefineKeyword) + { + //如果是自定义用户关键字,则根据语言tag获取 + return getUserDefineKeywords(); + } + + return 0; +} + + +// Returns the default EOL fill for a style. +bool QsciLexer::defaultEolFill(int) const +{ + return false; +} + + +// Returns the default font for a style. +QFont QsciLexer::defaultFont(int) const +{ + return defaultFont(); +} + + +// Returns the default font. +QFont QsciLexer::defaultFont() const +{ + return defFont; +} + + +// Sets the default font. +void QsciLexer::setDefaultFont(const QFont &f) +{ + defFont = f; +} + + +// Returns the default text colour for a style. +QColor QsciLexer::defaultColor(int) const +{ + return defaultColor(); +} + + +// Returns the default text colour. +QColor QsciLexer::defaultColor() const +{ + return defColor; +} + + +// Sets the default text colour. +void QsciLexer::setDefaultColor(const QColor &c) +{ + defColor = c; +} + + +// Returns the default paper colour for a styles. +QColor QsciLexer::defaultPaper(int) const +{ + return defaultPaper(); +} + + +// Returns the default paper colour. +QColor QsciLexer::defaultPaper() const +{ + return defPaper; +} + + +// Sets the default paper colour. +void QsciLexer::setDefaultPaper(const QColor &c) +{ + defPaper = c; + + // Normally the default values are only intended to provide defaults when a + // lexer is first setup because once a style has been referenced then a + // copy of the default is made. However the default paper is a special + // case because there is no other way to set the background colour used + // where there is no text. Therefore we also actively set it. + setPaper(c, QsciScintillaBase::STYLE_DEFAULT); +} + + +// Read properties from the settings. +bool QsciLexer::readProperties(QSettings &,const QString &) +{ + return true; +} + + +// Refresh all properties. +void QsciLexer::refreshProperties() +{ +} + + +// Write properties to the settings. +bool QsciLexer::writeProperties(QSettings &,const QString &) const +{ + return true; +} + + +// Restore the user settings. +bool QsciLexer::readSettings(QSettings &qs,const char *prefix) +{ + bool ok, flag, rc = true; + int num; + QString key, full_key; + QStringList fdesc; + + //原来是先读取默认值,在读取配置值。加入主题后,得先读取配置的默认值。 + //因为非默认主题的初始样式值,就该是默认样式值。只有读取配置的默认值,后面初始化样式时, + //才能获取到真正的样式默认值。 + if (m_themesId != 0) + { + key = QString("%1/%2/").arg(prefix).arg(language()); + + // Read the default foreground colour. + full_key = key + "defaultcolor"; + + ok = qs.contains(full_key); + num = qs.value(full_key).toString().toInt(&ok, 16); + + if (ok) + setDefaultColor(QColor((num >> 16) & 0xff, (num >> 8) & 0xff, num & 0xff)); + else + rc = false; + + // Read the default background colour. + full_key = key + "defaultpaper"; + + ok = qs.contains(full_key); + num = qs.value(full_key).toString().toInt(&ok, 16); + + if (ok) + setDefaultPaper(QColor((num >> 16) & 0xff, (num >> 8) & 0xff, num & 0xff)); + else + rc = false; + + // Read the default font. First try the deprecated format that uses an + // integer point size. + full_key = key + "defaultfont"; + + ok = qs.contains(full_key); + fdesc = qs.value(full_key).toStringList(); + + if (ok && fdesc.count() == 5) + { + QFont f; + + f.setFamily(fdesc[0]); + f.setPointSize(fdesc[1].toInt()); + f.setBold(fdesc[2].toInt()); + f.setItalic(fdesc[3].toInt()); + f.setUnderline(fdesc[4].toInt()); + + setDefaultFont(f); + } + else + rc = false; + } + + setStyleDefaults(); + + // Read the styles. + for (int i = 0; i <= QsciScintillaBase::STYLE_MAX; ++i) + { + // Ignore invalid styles. + if (description(i).isEmpty()) + continue; + + key = QString("%1/%2/style%3/").arg(prefix).arg(language()).arg(i); + + // Read the foreground colour. + full_key = key + "color"; + + ok = qs.contains(full_key); + num = qs.value(full_key).toString().toInt(&ok, 16); + + if (ok) + setColor(QColor((num >> 16) & 0xff, (num >> 8) & 0xff, num & 0xff), i); + else + rc = false; + + // Read the end-of-line fill. + full_key = key + "eolfill"; + + ok = qs.contains(full_key); + flag = qs.value(full_key, false).toBool(); + + if (ok) + setEolFill(flag, i); + else + rc = false; + + // Read the font. First try the deprecated format that uses an integer + // point size. + full_key = key + "font"; + + ok = qs.contains(full_key); + fdesc = qs.value(full_key).toStringList(); + + if (ok && fdesc.count() == 5) + { + QFont f; + + f.setFamily(fdesc[0]); + f.setPointSize(fdesc[1].toInt()); + f.setBold(fdesc[2].toInt()); + f.setItalic(fdesc[3].toInt()); + f.setUnderline(fdesc[4].toInt()); + + setFont(f, i); + } + else + rc = false; + + // Now try the newer font format that uses a floating point point size. + // It is not an error if it doesn't exist. + //full_key = key + "font2"; + + // ok = qs.contains(full_key); + // fdesc = qs.value(full_key).toStringList(); + + /*if (ok) + { + Allow for future versions with more fields. + if (fdesc.count() >= 5) + { + QFont f; + + f.setFamily(fdesc[0]); + f.setPointSizeF(fdesc[1].toDouble()); + f.setBold(fdesc[2].toInt()); + f.setItalic(fdesc[3].toInt()); + f.setUnderline(fdesc[4].toInt()); + + setFont(f, i); + } + else + { + rc = false; + } + }*/ + +#if 1 //不读取背景颜色,和主题保存一致 + // Read the background colour. + full_key = key + "paper"; + + ok = qs.contains(full_key); + num = qs.value(full_key).toString().toInt(&ok,16); + + if (ok) + setPaper(QColor((num >> 16) & 0xff, (num >> 8) & 0xff, num & 0xff), i); + else + rc = false; +#endif + } + + // Read the properties. + key = QString("%1/%2/properties/").arg(prefix).arg(language()); + + if (!readProperties(qs,key)) + rc = false; + + refreshProperties(); + + //只有默认主题才需要读取默认值。非默认主题,最前面已经读取过了。 + if (m_themesId == 0) + { + // Read the rest. + key = QString("%1/%2/").arg(prefix).arg(language()); + + // Read the default foreground colour. + full_key = key + "defaultcolor"; + + ok = qs.contains(full_key); + num = qs.value(full_key).toString().toInt(&ok, 16); + + if (ok) + setDefaultColor(QColor((num >> 16) & 0xff, (num >> 8) & 0xff, num & 0xff)); + else + rc = false; + + // Read the default background colour. + full_key = key + "defaultpaper"; + + ok = qs.contains(full_key); + num = qs.value(full_key).toString().toInt(&ok, 16); + + if (ok) + setDefaultPaper(QColor((num >> 16) & 0xff, (num >> 8) & 0xff, num & 0xff)); + else + rc = false; + + // Read the default font. First try the deprecated format that uses an + // integer point size. + full_key = key + "defaultfont"; + + ok = qs.contains(full_key); + fdesc = qs.value(full_key).toStringList(); + + if (ok && fdesc.count() == 5) + { + QFont f; + + f.setFamily(fdesc[0]); + f.setPointSize(fdesc[1].toInt()); + f.setBold(fdesc[2].toInt()); + f.setItalic(fdesc[3].toInt()); + f.setUnderline(fdesc[4].toInt()); + + setDefaultFont(f); + } + else + rc = false; + } + + // Now try the newer font format that uses a floating point point size. It + // is not an error if it doesn't exist. + //full_key = key + "defaultfont2"; + + //ok = qs.contains(full_key); + //fdesc = qs.value(full_key).toStringList(); + + //if (ok) + //{ + // // Allow for future versions with more fields. + // if (fdesc.count() >= 5) + // { + // QFont f; + + // f.setFamily(fdesc[0]); + // f.setPointSizeF(fdesc[1].toDouble()); + // f.setBold(fdesc[2].toInt()); + // f.setItalic(fdesc[3].toInt()); + // f.setUnderline(fdesc[4].toInt()); + + // setDefaultFont(f); + // } + // else + // { + // rc = false; + // } + //} + + full_key = key + "autoindentstyle"; + + ok = qs.contains(full_key); + num = qs.value(full_key).toInt(); + + if (ok) + setAutoIndentStyle(num); + else + rc = false; + + return rc; +} + + +// Save the user settings. +bool QsciLexer::writeSettings(QSettings &qs,const char *prefix) const +{ + bool rc = true; + QString key, fmt("%1"); + int num; + QStringList fdesc; + + setStyleDefaults(); + + // Write the styles. + for (int i = 0; i <= QsciScintillaBase::STYLE_MAX; ++i) + { + // Ignore invalid styles. + if (description(i).isEmpty()) + continue; + + QColor c; + + key = QString("%1/%2/style%3/").arg(prefix).arg(language()).arg(i); + + // Write the foreground colour. + c = color(i); + num = (c.red() << 16) | (c.green() << 8) | c.blue(); + + qs.setValue(key + "color", QString::number(num, 16)); + + // Write the end-of-line fill. + qs.setValue(key + "eolfill", eolFill(i)); + + // Write the font using the deprecated format. + QFont f = font(i); + + fdesc.clear(); + fdesc += f.family(); + fdesc += fmt.arg(f.pointSize()); + + // The casts are for Borland. + fdesc += fmt.arg((int)f.bold()); + fdesc += fmt.arg((int)f.italic()); + fdesc += fmt.arg((int)f.underline()); + + qs.setValue(key + "font", fdesc); + + // Write the font using the newer format. + //fdesc[1] = fmt.arg(f.pointSizeF()); + + //qs.setValue(key + "font2", fdesc); + +#if 1 //背景颜色和主题皮肤保存一致,故不写入背景颜色 + // Write the background colour. + c = paper(i); + num = (c.red() << 16) | (c.green() << 8) | c.blue(); + + qs.setValue(key + "paper", QString::number(num, 16)); +#endif + } + + // Write the properties. + key = QString("%1/%2/properties/").arg(prefix).arg(language()); + + if (!writeProperties(qs,key)) + rc = false; + + // Write the rest. + key = QString("%1/%2/").arg(prefix).arg(language()); + + // Write the default foreground colour. + num = (defColor.red() << 16) | (defColor.green() << 8) | defColor.blue(); + + qs.setValue(key + "defaultcolor", QString::number(num,16)); + +#if 1 + // Write the default background colour. + num = (defPaper.red() << 16) | (defPaper.green() << 8) | defPaper.blue(); + + qs.setValue(key + "defaultpaper", QString::number(num, 16)); +#endif + + // Write the default font using the deprecated format. + fdesc.clear(); + fdesc += defFont.family(); + fdesc += fmt.arg(defFont.pointSize()); + + // The casts are for Borland. + fdesc += fmt.arg((int)defFont.bold()); + fdesc += fmt.arg((int)defFont.italic()); + fdesc += fmt.arg((int)defFont.underline()); + + qs.setValue(key + "defaultfont", fdesc); + + // Write the font using the newer format. + //fdesc[1] = fmt.arg(defFont.pointSizeF()); + + //qs.setValue(key + "defaultfont2", fdesc); + + qs.setValue(key + "autoindentstyle", autoIndStyle); + + return rc; +} + + +// Return the auto-indentation style. +int QsciLexer::autoIndentStyle() +{ + // We can't do this in the ctor because we want the virtuals to work. + if (autoIndStyle < 0) + autoIndStyle = (blockStartKeyword() || blockStart() || blockEnd()) ? + 0 : QsciScintilla::AiMaintain; + + return autoIndStyle; +} + + +// Set the auto-indentation style. +void QsciLexer::setAutoIndentStyle(int autoindentstyle) +{ + autoIndStyle = autoindentstyle; +} + + +// Set the foreground colour for a style. +void QsciLexer::setColor(const QColor &c, int style) +{ + if (style >= 0) + { + styleData(style).color = c; + emit colorChanged(c, style); + } + else + for (int i = 0; i <= QsciScintillaBase::STYLE_MAX; ++i) + if (!description(i).isEmpty()) + setColor(c, i); +} + + +// Set the end-of-line fill for a style. +void QsciLexer::setEolFill(bool eolfill, int style) +{ + if (style >= 0) + { + styleData(style).eol_fill = eolfill; + emit eolFillChanged(eolfill, style); + } + else + for (int i = 0; i <= QsciScintillaBase::STYLE_MAX; ++i) + if (!description(i).isEmpty()) + setEolFill(eolfill, i); +} + + +// Set the font for a style. +void QsciLexer::setFont(const QFont &f, int style) +{ + if (style >= 0) + { + styleData(style).font = f; + emit fontChanged(f, style); + } + else + for (int i = 0; i <= QsciScintillaBase::STYLE_MAX; ++i) + if (!description(i).isEmpty()) + setFont(f, i); +} + + +// Set the background colour for a style. +void QsciLexer::setPaper(const QColor &c, int style) +{ + if (style >= 0) + { + styleData(style).paper = c; + emit paperChanged(c, style); + } + else + { + for (int i = 0; i <= QsciScintillaBase::STYLE_MAX; ++i) + if (!description(i).isEmpty()) + setPaper(c, i); + + emit paperChanged(c, QsciScintillaBase::STYLE_DEFAULT); + } +} void QsciLexer::setIsUserDefineKeywords(bool isUserDefine) { @@ -817,4 +913,39 @@ const char* QsciLexer::getUserDefineKeywords() return m_userDefineKeyword.data(); -} +} + +QByteArray QsciLexer::getCommentLineSymbol() +{ + return m_commentSymbol; +} + +void QsciLexer::setCommentLineSymbol(QByteArray comment) +{ + m_commentSymbol = comment; +} + +QByteArray QsciLexer::getCommentStart() +{ + return m_commentStart; +} + +QByteArray QsciLexer::getCommentEnd() +{ + return m_commentEnd; +} + +void QsciLexer::setCommentStart(QByteArray commentStart) +{ + m_commentStart = commentStart; +} + +void QsciLexer::setCommentEnd(QByteArray commentEnd) +{ + m_commentEnd = commentEnd; +} + +void QsciLexer::setCurThemes(int themesId) +{ + m_themesId = themesId; +} \ No newline at end of file diff --git a/src/qscint/src/qscilexerbash.cpp b/src/qscint/src/qscilexerbash.cpp index f259da0..0c049ee 100755 --- a/src/qscint/src/qscilexerbash.cpp +++ b/src/qscint/src/qscilexerbash.cpp @@ -29,6 +29,7 @@ QsciLexerBash::QsciLexerBash(QObject *parent) : QsciLexer(parent), fold_comments(false), fold_compact(true) { + m_commentSymbol = "#"; } diff --git a/src/qscint/src/qscilexerbatch.cpp b/src/qscint/src/qscilexerbatch.cpp index 71ea718..9682fc3 100755 --- a/src/qscint/src/qscilexerbatch.cpp +++ b/src/qscint/src/qscilexerbatch.cpp @@ -29,6 +29,7 @@ QsciLexerBatch::QsciLexerBatch(QObject *parent) : QsciLexer(parent) { + m_commentSymbol = "REM"; } diff --git a/src/qscint/src/qscilexercmake.cpp b/src/qscint/src/qscilexercmake.cpp index d5f4a0e..d850444 100755 --- a/src/qscint/src/qscilexercmake.cpp +++ b/src/qscint/src/qscilexercmake.cpp @@ -29,6 +29,7 @@ QsciLexerCMake::QsciLexerCMake(QObject *parent) : QsciLexer(parent), fold_atelse(false) { + m_commentSymbol = "#"; } diff --git a/src/qscint/src/qscilexercpp.cpp b/src/qscint/src/qscilexercpp.cpp index b0a434c..c7a3007 100755 --- a/src/qscint/src/qscilexercpp.cpp +++ b/src/qscint/src/qscilexercpp.cpp @@ -34,6 +34,9 @@ QsciLexerCPP::QsciLexerCPP(QObject *parent, bool caseInsensitiveKeywords) highlight_escape(false), vs_escape(false), nocase(caseInsensitiveKeywords) { + m_commentSymbol = "//"; + m_commentStart = "/*"; + m_commentEnd = "*/"; } diff --git a/src/qscint/src/qscilexercsharp.cpp b/src/qscint/src/qscilexercsharp.cpp index ad6045a..22427eb 100755 --- a/src/qscint/src/qscilexercsharp.cpp +++ b/src/qscint/src/qscilexercsharp.cpp @@ -29,6 +29,9 @@ QsciLexerCSharp::QsciLexerCSharp(QObject *parent) : QsciLexerCPP(parent) { + m_commentSymbol = "//"; + m_commentStart = "/*"; + m_commentEnd = "*/"; } diff --git a/src/qscint/src/qscilexercss.cpp b/src/qscint/src/qscilexercss.cpp index cf0b681..f3cc026 100755 --- a/src/qscint/src/qscilexercss.cpp +++ b/src/qscint/src/qscilexercss.cpp @@ -31,6 +31,8 @@ QsciLexerCSS::QsciLexerCSS(QObject *parent) fold_comments(false), fold_compact(true), hss_language(false), less_language(false), scss_language(false) { + m_commentStart = "/*"; + m_commentEnd = "*/"; } diff --git a/src/qscint/src/qscilexerfortran.cpp b/src/qscint/src/qscilexerfortran.cpp index 202b86c..fd940a2 100755 --- a/src/qscint/src/qscilexerfortran.cpp +++ b/src/qscint/src/qscilexerfortran.cpp @@ -29,6 +29,7 @@ QsciLexerFortran::QsciLexerFortran(QObject *parent) : QsciLexerFortran77(parent) { + m_commentSymbol = "!"; } diff --git a/src/qscint/src/qscilexerfortran77.cpp b/src/qscint/src/qscilexerfortran77.cpp index 60c7334..130cda7 100755 --- a/src/qscint/src/qscilexerfortran77.cpp +++ b/src/qscint/src/qscilexerfortran77.cpp @@ -29,6 +29,7 @@ QsciLexerFortran77::QsciLexerFortran77(QObject *parent) : QsciLexer(parent), fold_compact(true) { + m_commentSymbol = "!"; } diff --git a/src/qscint/src/qscilexerglobal.cpp b/src/qscint/src/qscilexerglobal.cpp index 6a0661d..ddc49c3 100755 --- a/src/qscint/src/qscilexerglobal.cpp +++ b/src/qscint/src/qscilexerglobal.cpp @@ -1,5 +1,9 @@ -#include "Qsci/qscilexerglobal.h" +#include "Qsci/qscilexerglobal.h" #include "Qsci/qsciscintilla.h" +#include "Scintilla.h" +#include "SciLexer.h" + +//golbal是一个特殊的语法编辑器,他不影响某一种具体的语法。而是对所有编辑器lexer以外的风格进行表示 QsciLexerGlobal::QsciLexerGlobal(QObject *parent) : QsciLexer(parent) @@ -16,28 +20,486 @@ int QsciLexerGlobal::lexerId() const // Returns the language name. const char* QsciLexerGlobal::language() const { - return "Gloabl"; + return "Global"; } QString QsciLexerGlobal::description(int style) const { - if (style == 0) + switch (style) { - return "All Language Modify"; + case GLOBAL_OVERRIDE: + return tr("Global override"); + case DEFAULT_STYLE: + return tr("Default"); + case INDENT_GUIDELINE: + return tr("Indent guideline style"); + case BRACE_HIGHIGHT: + return tr("Brace highlight style"); + case BAD_BRACE_COLOUR: + return tr("Bad brace colour"); + case CURRENT_LINE_BACKGROUND_COLOR: + return tr("Current line background colour"); + case SELECT_TEXT_COLOR: + return tr("Select text colour"); + case CARET_COLOUR: + return tr("Caret colour"); + case EDGE_COLOUR: + return tr("Edge colour"); + case LINE_NUMBER_MARGIN: + return tr("Line number margin"); + case BOOKMARK_MARGIN: + return tr("Bookmark margin"); + case FOLD: + return tr("Fold"); + case FOLD_ACTIVE: + return tr("Fold active"); + case FOLD_MARGIN: + return tr("Fold margin"); + case WHITE_SPACE_SYMBOL: + return tr("White space symbol"); + case SMART_HIGHLIGHTING: + return tr("Smart HighLighting"); + case FIND_MARK_STYLE: + return tr("Find Mark Style"); + case MARK_STYLE_1: + return tr("Mark Style 1"); + case MARK_STYLE_2: + return tr("Mark Style 2"); + case MARK_STYLE_3: + return tr("Mark Style 3"); + case MARK_STYLE_4: + return tr("Mark Style 4"); + case MARK_STYLE_5: + return tr("Mark Style 5"); + case INCREMENTAL_HIGHLIGHT: + return tr("Incremental highlight"); + case TAGS_MATCH_HIGHLIGHT: + return tr("Tags match highlight"); + case TAGS_ATTRIBUTE: + return tr("Tags attribute"); + /*case ACTIVE_TAB_FOCUSED: + return tr("Active tab focused"); + case ACTIVE_TAB_UNFOCUSED: + return tr("Active tab unfocused indicator"); + case ACTIVE_TAB_TEXT: + return tr("Active tab text"); + case INACTIVE_TABS: + return tr("Inactive tabs");*/ + case URL_HOVERRED: + return tr("URL hovered"); + default: + break; } return QString(); } +//字体大小。对于DEFAULT_STYLE BRACE_HIGHIGHT BAD_BRACE_COLOUR LINE_NUMBER_MARGIN +//四个特殊属性而言,他们的字体大小,是用来表示符号的大小的。 + QFont QsciLexerGlobal::defaultFont(int style) const +{ +#if defined(Q_OS_WIN) + QFont f("Courier New", 14); +#elif defined(Q_OS_MAC) + QFont f("Menlo", s_defaultFontSize); +#else + QFont f("Courier 10 Pitch", 14); +#endif + + switch (style) + { + + case INDENT_GUIDELINE: + case CURRENT_LINE_BACKGROUND_COLOR: + case SELECT_TEXT_COLOR: + case CARET_COLOUR: + case EDGE_COLOUR: + case BOOKMARK_MARGIN: + case FOLD: + case FOLD_ACTIVE: + case FOLD_MARGIN: + case WHITE_SPACE_SYMBOL: + case SMART_HIGHLIGHTING: + case FIND_MARK_STYLE: + case MARK_STYLE_1: + case MARK_STYLE_2: + case MARK_STYLE_3: + case MARK_STYLE_4: + case MARK_STYLE_5: + case INCREMENTAL_HIGHLIGHT: + case TAGS_MATCH_HIGHLIGHT: + case TAGS_ATTRIBUTE: + /*case ACTIVE_TAB_FOCUSED: + case ACTIVE_TAB_UNFOCUSED: + case ACTIVE_TAB_TEXT: + case INACTIVE_TABS:*/ + case URL_HOVERRED: + //这些都是不能设置字体的,统一设置为空 + f.setFamily(""); + f.setPointSize(-1); + break; + + case GLOBAL_OVERRIDE: + case BAD_BRACE_COLOUR: + case DEFAULT_STYLE: + case BRACE_HIGHIGHT: + return f; + + case LINE_NUMBER_MARGIN: + //这个对应STYLE_LINENUMBER的默认大小为10 + f.setPointSize(12); + return f; + default: + break; + } + return QsciLexer::s_defaultLangFont; +} + + +// Returns the foreground colour of the text for a style. +QColor QsciLexerGlobal::defaultColor(int style) const { switch (style) { - case 0: - return QsciLexer::s_defaultLangFont; - break; + case GLOBAL_OVERRIDE: + return QColor(0xFFFF80); + + case DEFAULT_STYLE: + return QColor(Qt::black); + + case INDENT_GUIDELINE: + return QColor(0xC0C0C0); + + case BRACE_HIGHIGHT: + return QColor(0xFF0000); + + case BAD_BRACE_COLOUR: + return QColor(0x800000); + + case CURRENT_LINE_BACKGROUND_COLOR: + return QColor(0x0080C0); + + case SELECT_TEXT_COLOR: + return QColor(Qt::black); + + case CARET_COLOUR: + return QColor(0x8000FF); + + case EDGE_COLOUR: + return QColor(0x80FFFF); + + case LINE_NUMBER_MARGIN: + return QColor(0x808080); + + case BOOKMARK_MARGIN: + return QColor(0xEEEEEC); + + case FOLD: + return QColor(0x808080); + + case FOLD_ACTIVE: + return QColor(0xFF0000); + + case FOLD_MARGIN: + return QColor(0xFFFFFF); + + case WHITE_SPACE_SYMBOL: + return QColor(0xFFB56A); + + case SMART_HIGHLIGHTING: + return QColor(0x00ff00); + + case FIND_MARK_STYLE: + return QColor(0xFCAF3E); + + case MARK_STYLE_1: + return QColor(0x555753); + + case MARK_STYLE_2: + return QColor(0xFCAF3E); + + case MARK_STYLE_3: + return QColor(0xFAAA3C); + + case MARK_STYLE_4: + return QColor(0xFFCAB0); + + case MARK_STYLE_5: + return QColor(Qt::black); + + case INCREMENTAL_HIGHLIGHT: + return QColor(0x808080); + + case TAGS_MATCH_HIGHLIGHT: + return QColor(0xFFCAB0); + + case TAGS_ATTRIBUTE: + return QColor(0xFFCAB0); + + /*case ACTIVE_TAB_FOCUSED: + return QColor(0xFAAA3C); + + case ACTIVE_TAB_UNFOCUSED: + return QColor(0xFFCAB0); + + case ACTIVE_TAB_TEXT: + return QColor(Qt::black); + + case INACTIVE_TABS: + return QColor(0x808080);*/ + + case URL_HOVERRED: + return QColor(0xFFFF80); + default: break; - } - return QsciLexer::s_defaultLangFont; + } + + return QsciLexer::defaultColor(style); +} + + +//global其实不是一个风格,它里面的风格是约束编辑器其他细节设置的。但是保存又是安装内部的styleid来进行的。 +//故提供该函数,把内部风格转换为外部的风格id功能。没有则为-2 +int QsciLexerGlobal::getRealStyleId(int style) +{ + switch (style) + { + //可设置前景、背景、字体 + case DEFAULT_STYLE: + return STYLE_DEFAULT; + + case INDENT_GUIDELINE: + return STYLE_INDENTGUIDE; + + case BRACE_HIGHIGHT: + return STYLE_BRACELIGHT; + + case BAD_BRACE_COLOUR: + return STYLE_BRACEBAD; + + case CARET_COLOUR: + return SCI_SETCARETFORE; + + case LINE_NUMBER_MARGIN: + return STYLE_LINENUMBER; + + case SMART_HIGHLIGHTING: + return SCE_UNIVERSAL_FOUND_STYLE_SMART; + + case FIND_MARK_STYLE: + return SCE_UNIVERSAL_FOUND_STYLE; + + case MARK_STYLE_1: + return SCE_UNIVERSAL_FOUND_STYLE_EXT1; + + case MARK_STYLE_2: + return SCE_UNIVERSAL_FOUND_STYLE_EXT2; + + case MARK_STYLE_3: + return SCE_UNIVERSAL_FOUND_STYLE_EXT3; + + case MARK_STYLE_4: + return SCE_UNIVERSAL_FOUND_STYLE_EXT4; + + case MARK_STYLE_5: + return SCE_UNIVERSAL_FOUND_STYLE_EXT5; + + case INCREMENTAL_HIGHLIGHT: + return SCE_UNIVERSAL_FOUND_STYLE_INC; + + case TAGS_MATCH_HIGHLIGHT: + return SCE_UNIVERSAL_TAGMATCH; + + case TAGS_ATTRIBUTE: + return SCE_UNIVERSAL_TAGATTR; + + default: + break; + } + + //-1是表示所以,已经被占用,所以使用-2 + return -2; +} + +QColor QsciLexerGlobal::defaultPaper(int style) const +{ + switch (style) + { + case GLOBAL_OVERRIDE: + return QColor(0xFF8000); + + case DEFAULT_STYLE: + return QColor(0xFFFFFF); + + case INDENT_GUIDELINE: + return QColor(0xFFFFFF); + + case BRACE_HIGHIGHT: + return QColor(0xFFFFFF); + + case BAD_BRACE_COLOUR: + return QColor(0xFFFFFF); + + case CURRENT_LINE_BACKGROUND_COLOR: + return QColor(0xE8E8FF); + + case SELECT_TEXT_COLOR: + return QColor(0xC0C0C0); + + case CARET_COLOUR: + return QColor(0x919994); + + case EDGE_COLOUR: + return QColor(0x112435); + + case LINE_NUMBER_MARGIN: + return QColor(0xE4E4E4); + + case BOOKMARK_MARGIN: + return QColor(0xE0E0E0); + + case FOLD: + return QColor(0xF3F3F3); + + case FOLD_ACTIVE: + return QColor(0x2E3436); + + case FOLD_MARGIN: + return QColor(0xE9E9E9); + + case WHITE_SPACE_SYMBOL: + return QColor(0x80FF00); + + case SMART_HIGHLIGHTING: + return QColor(0x00FF00); + + case FIND_MARK_STYLE: + return QColor(0xFF0000); + + case MARK_STYLE_1: + return QColor(0x00FFFF); + + case MARK_STYLE_2: + return QColor(0xFF8000); + + case MARK_STYLE_3: + return QColor(0xFFFF00); + + case MARK_STYLE_4: + return QColor(0x8000FF); + + case MARK_STYLE_5: + return QColor(0x008000); + + case INCREMENTAL_HIGHLIGHT: + return QColor(0x0080FF); + + case TAGS_MATCH_HIGHLIGHT: + return QColor(0x8000FF); + + case TAGS_ATTRIBUTE: + return QColor(0xFFFF00); + + //case ACTIVE_TAB_FOCUSED: + // return QColor(0x8000FF); + + //case ACTIVE_TAB_UNFOCUSED: + // return QColor(0xFFFF00); + + //case ACTIVE_TAB_TEXT: + // return QColor(0xFF0000); + + //case INACTIVE_TABS: + // return QColor(0xC0C0C0); + + case URL_HOVERRED: + return QColor(0xC0C0C0); + + default: + break; + } + + return QsciLexer::defaultPaper(style); +} +//enum CHANGE_OPER_BIT { +// FG_BIT = 1, +// BG_BIT = 2, +// FONT_BIT = 4, +// SIZE_BIT = 8, +//}; + +//全局样式哪些位可以修改。在设置的界面,把不能修改的界面回调 +int QsciLexerGlobal::changeOperBit(int style) const +{ + switch (style) + { + case GLOBAL_OVERRIDE: + return ALL_OPER_BIT; + + case DEFAULT_STYLE: + return ALL_OPER_BIT; + + case INDENT_GUIDELINE: + return FG_BIT | BG_BIT; + + case BRACE_HIGHIGHT: + return ALL_OPER_BIT; + + case BAD_BRACE_COLOUR: + return ALL_OPER_BIT; + + case CURRENT_LINE_BACKGROUND_COLOR: + return BG_BIT; + + case SELECT_TEXT_COLOR: + return FG_BIT | BG_BIT; + + case CARET_COLOUR: + return FG_BIT; + + case EDGE_COLOUR: + return FG_BIT; + + case LINE_NUMBER_MARGIN: + return ALL_OPER_BIT; + + case BOOKMARK_MARGIN: + return BG_BIT; + + case FOLD: + case FOLD_ACTIVE: + case FOLD_MARGIN: + return FG_BIT | BG_BIT; + + case WHITE_SPACE_SYMBOL: + return FG_BIT; + + case SMART_HIGHLIGHTING: + return FG_BIT; + + case FIND_MARK_STYLE: + return FG_BIT; + + case MARK_STYLE_1: + case MARK_STYLE_2: + case MARK_STYLE_3: + case MARK_STYLE_4: + case MARK_STYLE_5: + return BG_BIT; + + case INCREMENTAL_HIGHLIGHT: + break; + case TAGS_MATCH_HIGHLIGHT: + return FG_BIT; + case TAGS_ATTRIBUTE: + return FG_BIT; + case URL_HOVERRED: + return FG_BIT; + + default: + break; + } + return 0; } diff --git a/src/qscint/src/qscilexergo.cpp b/src/qscint/src/qscilexergo.cpp index 52580a2..bc56423 100755 --- a/src/qscint/src/qscilexergo.cpp +++ b/src/qscint/src/qscilexergo.cpp @@ -28,6 +28,9 @@ QsciLexerGO::QsciLexerGO(QObject *parent) : QsciLexerCPP(parent) { + m_commentSymbol = "//"; + m_commentStart = "/*"; + m_commentEnd = "*/"; } diff --git a/src/qscint/src/qscilexerhtml.cpp b/src/qscint/src/qscilexerhtml.cpp index 6aefa83..da7b6fa 100755 --- a/src/qscint/src/qscilexerhtml.cpp +++ b/src/qscint/src/qscilexerhtml.cpp @@ -35,6 +35,9 @@ QsciLexerHTML::QsciLexerHTML(QObject *parent) fold_script_comments(false), fold_script_heredocs(false), django_templates(false), mako_templates(false) { + m_commentSymbol = ""; + m_commentStart = ""; } @@ -565,7 +568,7 @@ QString QsciLexerHTML::description(int style) const switch (style) { case Default: - return tr("HTML default"); + return tr("Default"); case Tag: return tr("Tag"); diff --git a/src/qscint/src/qscilexerjava.cpp b/src/qscint/src/qscilexerjava.cpp index 9726c56..d0a314d 100755 --- a/src/qscint/src/qscilexerjava.cpp +++ b/src/qscint/src/qscilexerjava.cpp @@ -25,6 +25,9 @@ QsciLexerJava::QsciLexerJava(QObject *parent) : QsciLexerCPP(parent) { + m_commentSymbol = "//"; + m_commentStart = "/*"; + m_commentEnd = "*/"; } diff --git a/src/qscint/src/qscilexerjavascript.cpp b/src/qscint/src/qscilexerjavascript.cpp index d610ae3..a49b4ba 100755 --- a/src/qscint/src/qscilexerjavascript.cpp +++ b/src/qscint/src/qscilexerjavascript.cpp @@ -39,6 +39,9 @@ const char *QsciLexerJavaScript::keywordClass = QsciLexerJavaScript::QsciLexerJavaScript(QObject *parent) : QsciLexerCPP(parent) { + m_commentSymbol = "//"; + m_commentStart = "/*"; + m_commentEnd = "*/"; } diff --git a/src/qscint/src/qscilexerlua.cpp b/src/qscint/src/qscilexerlua.cpp index c2b6f8e..870b37b 100755 --- a/src/qscint/src/qscilexerlua.cpp +++ b/src/qscint/src/qscilexerlua.cpp @@ -29,6 +29,7 @@ QsciLexerLua::QsciLexerLua(QObject *parent) : QsciLexer(parent), fold_compact(true) { + m_commentSymbol = "--"; } diff --git a/src/qscint/src/qscilexermakefile.cpp b/src/qscint/src/qscilexermakefile.cpp index f38f164..f1418db 100755 --- a/src/qscint/src/qscilexermakefile.cpp +++ b/src/qscint/src/qscilexermakefile.cpp @@ -28,6 +28,7 @@ QsciLexerMakefile::QsciLexerMakefile(QObject *parent) : QsciLexer(parent) { + m_commentSymbol = "#"; } diff --git a/src/qscint/src/qscilexermatlab.cpp b/src/qscint/src/qscilexermatlab.cpp index 6ff0825..d817d73 100755 --- a/src/qscint/src/qscilexermatlab.cpp +++ b/src/qscint/src/qscilexermatlab.cpp @@ -28,6 +28,7 @@ QsciLexerMatlab::QsciLexerMatlab(QObject *parent) : QsciLexer(parent) { + m_commentSymbol = "%"; } diff --git a/src/qscint/src/qscilexernsis.cpp b/src/qscint/src/qscilexernsis.cpp index 8ccbff5..5dec443 100755 --- a/src/qscint/src/qscilexernsis.cpp +++ b/src/qscint/src/qscilexernsis.cpp @@ -8,7 +8,7 @@ QsciLexerNsis::QsciLexerNsis(QObject *parent) : QsciLexer(parent) { - + m_commentSymbol = "#"; } QsciLexerNsis::~QsciLexerNsis() @@ -123,7 +123,7 @@ QString QsciLexerNsis::description(int style) const switch (style) { case NSIS_DEFAULT: - return tr("DEFAULT"); + return tr("Default"); case NSIS_COMMENT: return tr("COMMENT"); case NSIS_STRINGDQ: diff --git a/src/qscint/src/qscilexerpascal.cpp b/src/qscint/src/qscilexerpascal.cpp index 543ed24..38d2daf 100755 --- a/src/qscint/src/qscilexerpascal.cpp +++ b/src/qscint/src/qscilexerpascal.cpp @@ -31,6 +31,8 @@ QsciLexerPascal::QsciLexerPascal(QObject *parent) fold_comments(false), fold_compact(true), fold_preproc(false), smart_highlight(true) { + m_commentStart = "{"; + m_commentEnd = "}"; } diff --git a/src/qscint/src/qscilexerperl.cpp b/src/qscint/src/qscilexerperl.cpp index b86e24a..27b6be6 100755 --- a/src/qscint/src/qscilexerperl.cpp +++ b/src/qscint/src/qscilexerperl.cpp @@ -31,6 +31,7 @@ QsciLexerPerl::QsciLexerPerl(QObject *parent) fold_atelse(false), fold_comments(false), fold_compact(true), fold_packages(true), fold_pod_blocks(true) { + m_commentSymbol = "#"; } diff --git a/src/qscint/src/qscilexerproperties.cpp b/src/qscint/src/qscilexerproperties.cpp index 70e1cae..ae00c9c 100755 --- a/src/qscint/src/qscilexerproperties.cpp +++ b/src/qscint/src/qscilexerproperties.cpp @@ -29,6 +29,7 @@ QsciLexerProperties::QsciLexerProperties(QObject *parent) : QsciLexer(parent), fold_compact(true), initial_spaces(true) { + m_commentSymbol = "#"; } diff --git a/src/qscint/src/qscilexerpython.cpp b/src/qscint/src/qscilexerpython.cpp index 6b05421..fd06ddc 100755 --- a/src/qscint/src/qscilexerpython.cpp +++ b/src/qscint/src/qscilexerpython.cpp @@ -39,6 +39,7 @@ QsciLexerPython::QsciLexerPython(QObject *parent) indent_warn(NoWarning), strings_over_newline(false), v2_unicode(true), v3_binary_octal(true), v3_bytes(true), highlight_subids(true) { + m_commentSymbol = "#"; } diff --git a/src/qscint/src/qscilexerruby.cpp b/src/qscint/src/qscilexerruby.cpp index 9d6b6c9..25c6ca4 100755 --- a/src/qscint/src/qscilexerruby.cpp +++ b/src/qscint/src/qscilexerruby.cpp @@ -29,6 +29,7 @@ QsciLexerRuby::QsciLexerRuby(QObject *parent) : QsciLexer(parent), fold_comments(false), fold_compact(true) { + m_commentSymbol = "#"; } diff --git a/src/qscint/src/qscilexerrust.cpp b/src/qscint/src/qscilexerrust.cpp index 3493771..2c11825 100755 --- a/src/qscint/src/qscilexerrust.cpp +++ b/src/qscint/src/qscilexerrust.cpp @@ -8,7 +8,9 @@ QsciLexerRust::QsciLexerRust(QObject *parent) : QsciLexer(parent) { - + m_commentSymbol = "//"; + m_commentStart = "/*"; + m_commentEnd = "*/"; } QsciLexerRust::~QsciLexerRust() @@ -69,7 +71,7 @@ QString QsciLexerRust::description(int style) const switch (style) { case RUST_DEFAULT: - return "default"; + return "Default"; case RUST_COMMENTBLOCK: return "comment"; case RUST_COMMENTLINE: diff --git a/src/qscint/src/qscilexersql.cpp b/src/qscint/src/qscilexersql.cpp index 9550f14..1f4b93d 100755 --- a/src/qscint/src/qscilexersql.cpp +++ b/src/qscint/src/qscilexersql.cpp @@ -33,6 +33,9 @@ QsciLexerSQL::QsciLexerSQL(QObject *parent) numbersign_comment(false), backslash_escapes(false), allow_dotted_word(false) { + m_commentSymbol = "--"; + m_commentStart = "/*"; + m_commentEnd = "*/"; } diff --git a/src/qscint/src/qscilexertext.cpp b/src/qscint/src/qscilexertext.cpp index 9ef5660..9017bad 100755 --- a/src/qscint/src/qscilexertext.cpp +++ b/src/qscint/src/qscilexertext.cpp @@ -18,6 +18,7 @@ QsciLexerText::QsciLexerText(QObject *parent) : QsciLexer(parent) { setLexerId(L_TXT); + m_commentSymbol = "#"; } QsciLexerText::~QsciLexerText() diff --git a/src/qscint/src/qscilexervb.cpp b/src/qscint/src/qscilexervb.cpp index ab5c20c..d537335 100755 --- a/src/qscint/src/qscilexervb.cpp +++ b/src/qscint/src/qscilexervb.cpp @@ -4,6 +4,7 @@ QsciLexerVB::QsciLexerVB(QObject *parent) : QsciLexer(parent) { setLexerId(L_VB); + m_commentSymbol = "'"; } QsciLexerVB::~QsciLexerVB() @@ -85,7 +86,7 @@ QString QsciLexerVB::description(int style) const switch (style) { case VB_DEFAULT: - return "default"; + return "Default"; case VB_COMMENT: return "comment"; case VB_NUMBER: diff --git a/src/qscint/src/qscilexerverilog.cpp b/src/qscint/src/qscilexerverilog.cpp index 0a3f26b..d1c36d7 100755 --- a/src/qscint/src/qscilexerverilog.cpp +++ b/src/qscint/src/qscilexerverilog.cpp @@ -31,6 +31,9 @@ QsciLexerVerilog::QsciLexerVerilog(QObject *parent) fold_atelse(false), fold_comments(false), fold_compact(true), fold_preproc(false), fold_atmodule(false) { + m_commentSymbol = "//"; + m_commentStart = "/*"; + m_commentEnd = "*/"; } diff --git a/src/qscint/src/qscilexervhdl.cpp b/src/qscint/src/qscilexervhdl.cpp index 48f9489..68cabe0 100755 --- a/src/qscint/src/qscilexervhdl.cpp +++ b/src/qscint/src/qscilexervhdl.cpp @@ -31,6 +31,9 @@ QsciLexerVHDL::QsciLexerVHDL(QObject *parent) fold_comments(true), fold_compact(true), fold_atelse(true), fold_atbegin(true), fold_atparenth(true) { + m_commentSymbol = "--"; + m_commentStart = "/*"; + m_commentEnd = "*/"; } diff --git a/src/qscint/src/qscilexerxml.cpp b/src/qscint/src/qscilexerxml.cpp index d784b6f..24976e9 100755 --- a/src/qscint/src/qscilexerxml.cpp +++ b/src/qscint/src/qscilexerxml.cpp @@ -29,6 +29,9 @@ QsciLexerXML::QsciLexerXML(QObject *parent) : QsciLexerHTML(parent), scripts(true) { + m_commentSymbol = ""; + m_commentStart = ""; } diff --git a/src/qscint/src/qscilexeryaml.cpp b/src/qscint/src/qscilexeryaml.cpp index a9e7135..f15c758 100755 --- a/src/qscint/src/qscilexeryaml.cpp +++ b/src/qscint/src/qscilexeryaml.cpp @@ -29,6 +29,7 @@ QsciLexerYAML::QsciLexerYAML(QObject *parent) : QsciLexer(parent), fold_comments(false) { + m_commentSymbol = "#"; } diff --git a/src/qscint/src/qscintilla.pro b/src/qscint/src/qscintilla.pro index 7557811..2704d72 100755 --- a/src/qscint/src/qscintilla.pro +++ b/src/qscint/src/qscintilla.pro @@ -21,7 +21,7 @@ !win32:VERSION = 15.1.0 TEMPLATE = lib -CONFIG += qt warn_off thread exceptions hide_symbols release staticlib +CONFIG += qt warn_off thread exceptions hide_symbols debug staticlib CONFIG(debug, debug|release) { mac: { diff --git a/src/qscint/src/qscintilla.pro.user b/src/qscint/src/qscintilla.pro.user new file mode 100755 index 0000000..09e53f5 --- /dev/null +++ b/src/qscint/src/qscintilla.pro.user @@ -0,0 +1,261 @@ + + + + + + EnvironmentId + {ee8a8311-48c9-435d-8d33-c3e67e1c3f3d} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + false + true + false + 0 + true + true + 0 + 8 + true + false + 1 + true + true + true + *.md, *.MD, Makefile + false + true + true + + + + ProjectExplorer.Project.PluginSettings + + + true + false + true + true + true + true + + + 0 + true + + true + true + Builtin.DefaultTidyAndClazy + 3 + + + + true + + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop Qt 5.15.2 MSVC2019 64bit + Desktop Qt 5.15.2 MSVC2019 64bit + qt.qt5.5152.win64_msvc2019_64_kit + 1 + 0 + 0 + + 0 + D:\notepad--\qscint\src\..\build-qscintilla-Desktop_Qt_5_15_2_MSVC2019_64bit-Debug + D:/notepad--/qscint/build-qscintilla-Desktop_Qt_5_15_2_MSVC2019_64bit-Debug + + + true + QtProjectManager.QMakeBuildStep + false + + + + true + Qt4ProjectManager.MakeStep + + 2 + 构建 + 构建 + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + clean + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + D:\notepad--\qscint\src\..\build-qscintilla-Desktop_Qt_5_15_2_MSVC2019_64bit-Release + D:/notepad--/qscint/build-qscintilla-Desktop_Qt_5_15_2_MSVC2019_64bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + + + true + Qt4ProjectManager.MakeStep + + 2 + 构建 + 构建 + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + clean + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + 0 + + + 0 + D:\notepad--\qscint\src\..\build-qscintilla-Desktop_Qt_5_15_2_MSVC2019_64bit-Profile + D:/notepad--/qscint/build-qscintilla-Desktop_Qt_5_15_2_MSVC2019_64bit-Profile + + + true + QtProjectManager.QMakeBuildStep + false + + + + true + Qt4ProjectManager.MakeStep + + 2 + 构建 + 构建 + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + clean + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + 0 + 0 + + 3 + + + 0 + 部署 + 部署 + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + 1 + + true + true + true + + 2 + + ProjectExplorer.CustomExecutableRunConfiguration + + false + true + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/src/qscint/src/qscintilla.vcxproj b/src/qscint/src/qscintilla.vcxproj index 1662f5f..dadc678 100755 --- a/src/qscint/src/qscintilla.vcxproj +++ b/src/qscint/src/qscintilla.vcxproj @@ -1,121 +1,51 @@  - - Release - x64 - Debug x64 + + Release + x64 + {9BC42707-EE25-3B28-9906-F7919E273020} - qmyedit_qt5 + qmyedit_qt5d QtVS_v304 10.0.19041.0 10.0.19041.0 - $(MSBuildProjectDirectory)\QtMsBuild - + $(MSBuildProjectDirectory)\QtMsBuild - - v141 - ..\..\x64\Release\ - false - NotSet - StaticLibrary - release\ - qmyedit_qt5 - v141 - ..\..\x64\Release\ + ..\..\x64\Debug\ false NotSet StaticLibrary debug\ - qmyedit_qt5 + qmyedit_qt5d - - - - + + v141 + ..\..\x64\Debug\ + false + NotSet + StaticLibrary + release\ + qmyedit_qt5d + + - - - - - - + + - - ..\..\x64\Debug\ - debug\ - qmyedit_qt5d - true - - - ..\..\x64\Release\ - release\ - qmyedit_qt5 - true - - - 5.15.2_msvc2019_64 - core;gui;widgets;printsupport - - - 5.15.2_msvc2019_64 - core;gui;widgets;printsupport - - - - - - - GeneratedFiles\$(ConfigurationName);GeneratedFiles;.;..\scintilla\include;..\scintilla\lexlib;..\scintilla\src;..\scintilla\boostregex;release;/include;%(AdditionalIncludeDirectories) - -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) - release\ - false - None - Sync - release\ - MaxSpeed - _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;SCINTILLA_QT;SCI_LEXER;INCLUDE_DEPRECATED_FEATURES;NDEBUG;QT_NO_DEBUG;%(PreprocessorDefinitions) - false - - - MultiThreadedDLL - true - true - TurnOffAllWarnings - true - - - $(OutDir)\qmyedit_qt5.lib - true - - - Unsigned - None - 0 - - - _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;SCINTILLA_QT;SCI_LEXER;INCLUDE_DEPRECATED_FEATURES;NDEBUG;QT_NO_DEBUG;QT_PRINTSUPPORT_LIB;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;%(PreprocessorDefinitions) - - - msvc - ./$(Configuration)/moc_predefs.h - Moc'ing %(Identity)... - output - $(Configuration) - moc_%(Filename).cpp - - + ..\..\x64\Debug\release\qmyedit_qt5dtrue..\..\x64\Debug\debug\qmyedit_qt5dtrue5.12.10_msvc2017_64core;gui;widgets;printsupport5.12.10_msvc2017_64core;gui;widgets;printsupport + GeneratedFiles\$(ConfigurationName);GeneratedFiles;.;..\scintilla\include;..\scintilla\lexlib;..\scintilla\src;..\scintilla\boostregex;debug;/include;%(AdditionalIncludeDirectories) @@ -132,8 +62,7 @@ true true TurnOffAllWarnings - true - + true $(OutDir)\qmyedit_qt5d.lib true @@ -146,15 +75,38 @@ _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;SCINTILLA_QT;SCI_LEXER;INCLUDE_DEPRECATED_FEATURES;QT_PRINTSUPPORT_LIB;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;_DEBUG;%(PreprocessorDefinitions) - - msvc - ./$(Configuration)/moc_predefs.h - Moc'ing %(Identity)... - output - $(Configuration) - moc_%(Filename).cpp - - + msvc./$(Configuration)/moc_predefs.hMoc'ing %(Identity)...output$(Configuration)moc_%(Filename).cpp + + + GeneratedFiles\$(ConfigurationName);GeneratedFiles;.;..\scintilla\include;..\scintilla\lexlib;..\scintilla\src;..\scintilla\boostregex;release;/include;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + release\ + false + None + Sync + release\ + MaxSpeed + _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;SCINTILLA_QT;SCI_LEXER;INCLUDE_DEPRECATED_FEATURES;QT_NO_DEBUG;NDEBUG;%(PreprocessorDefinitions) + false + + MultiThreadedDLL + true + true + TurnOffAllWarnings + true + + $(OutDir)\qmyedit_qt5d.lib + true + + + Unsigned + None + 0 + + + _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;SCINTILLA_QT;SCI_LEXER;INCLUDE_DEPRECATED_FEATURES;QT_NO_DEBUG;QT_PRINTSUPPORT_LIB;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;%(PreprocessorDefinitions) + + msvc./$(Configuration)/moc_predefs.hMoc'ing %(Identity)...output$(Configuration)moc_%(Filename).cpp @@ -421,12 +373,28 @@ + + + + + + + + + + + + + + + + @@ -444,142 +412,663 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Document - true $(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs) cl -Bx"$(QTDIR)\bin\qmake.exe" -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -Zi -MDd -EHsc -W0 -E $(QTDIR)\mkspecs\features\data\dummy.cpp 2>NUL >debug\moc_predefs.h Generate moc_predefs.h debug\moc_predefs.h;%(Outputs) + true Document + true $(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs) cl -Bx"$(QTDIR)\bin\qmake.exe" -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -O2 -MD -EHsc -W0 -E $(QTDIR)\mkspecs\features\data\dummy.cpp 2>NUL >release\moc_predefs.h Generate moc_predefs.h release\moc_predefs.h;%(Outputs) - true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + \ No newline at end of file diff --git a/src/qscint/src/qscintilla.vcxproj.user b/src/qscint/src/qscintilla.vcxproj.user index 4105086..12a6cee 100755 --- a/src/qscint/src/qscintilla.vcxproj.user +++ b/src/qscint/src/qscintilla.vcxproj.user @@ -1,10 +1,10 @@  - + - 2022-12-11T10:28:17.8337419Z + 2023-01-07T07:01:28.9194699Z - 2022-12-11T10:28:18.9624294Z + 2023-01-07T07:01:28.9902806Z \ No newline at end of file diff --git a/src/qscint/src/qsciscintilla.cpp b/src/qscint/src/qsciscintilla.cpp index 3d335d4..0a00e64 100755 --- a/src/qscint/src/qsciscintilla.cpp +++ b/src/qscint/src/qsciscintilla.cpp @@ -3713,10 +3713,12 @@ void QsciScintilla::handleUpdateUI(int) if (line != oldLine) { oldLine = line; - emit cursorPosChange(line, newPos); - } + emit cursorPosChange(line, newPos); + } } + addHotSpot(); + if (braceMode != NoBraceMatch) braceMatch(); diff --git a/src/qss/black.qss b/src/qss/black.qss index 3c592a8..3419957 100755 --- a/src/qss/black.qss +++ b/src/qss/black.qss @@ -68,11 +68,16 @@ border:1px solid #00BB9E; background:qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 #646464,stop:1 #525252); } +QToolButton,QToolButton:disabled{ + color:#000000; + background-color:#ffffff; +} + QToolButton#leftBt,#leftSaveBt,#rightBt,#rightSaveBt,#leftReload,#rightReload,#toolButton,#toolButton1,#subToolButton,#addToolButton,#selectDir,#toolButtonBrowse,#definedFilterExt,#proLangBt{ border-style:none; border:1px solid #646464; background-color:#383838; -/*color:#386487;*/ +color:#ffffff; padding:1px; min-height:8px; border-radius:1px; @@ -82,22 +87,33 @@ QToolButton#leftBt:hover,#leftSaveBt:hover,#rightBt:hover,#rightSaveBt:hover,#le background:qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 #484848,stop:1 #383838); } -QToolBar,QMessageBox,QHeaderView::section{ - background-color:#444444; +QToolBar{ + background-color:rgb(232,232,232); + border:none; + padding:1px; +} + +QHeaderView{ + background-color:#383838; border: none; padding:0px; } +QFrame#leftSrc,QFrame#rightSrc{ + border:none; + padding:0px; +} + QTabBar QToolButton[accessibleName="Scroll Left"]{border:0px;background-color:#444444;} QTabBar QToolButton[accessibleName="Scroll Right"]{border:0px;background-color:#444444;} -QLineEdit,QTextEdit,QPlainTextEdit,QSpinBox,QDoubleSpinBox,QComboBox,QDateEdit,QTimeEdit,QDateTimeEdit{ +QLineEdit,QTextEdit,QPlainTextEdit,QSpinBox,QDoubleSpinBox,QComboBox,QDateEdit,QTimeEdit,QDateTimeEdit,QMessageBox{ border:1px solid #242424; border-radius:3px; padding:2px; background:none; -selection-background-color:#484848; +selection-background-color:#000000; selection-color:#DCDCDC; } @@ -132,16 +148,17 @@ border:1px solid #242424; color:#DCDCDC; padding:5px; min-height:15px; +min-width:50px; border-radius:5px; background:qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 #484848,stop:1 #383838); } -.QPushButton:hover,.QToolButton:hover{ +.QPushButton:hover{ background:qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 #646464,stop:1 #525252); border:0px; } -.QPushButton:pressed,.QToolButton:pressed{ +.QPushButton:pressed{ background:qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 #484848,stop:1 #383838); } @@ -278,21 +295,23 @@ top:1px; } QMenuBar::item{ -color:#DCDCDC; -background-color:#484848; +color:#000000; +background-color:#e8e8e8; margin:0px; padding:3px 10px; } QMenu,QMenuBar,QMenu:disabled,QMenuBar:disabled{ -color:#DCDCDC; -background-color:#484848; -border:1px solid #242424; +color:#000000; +background-color:#e8e8e8; +border:0px solid #242424; margin:0px; } QMenu::item{ padding:3px 20px; +min-width:80; +margin-left:3px; } QMenu::indicator{ @@ -512,15 +531,14 @@ background:qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 #646464,stop:1 } QTabBar::tab{ -border:0px solid #242424; color:#DCDCDC; -background:qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 #646464,stop:1 #525252); +background-color:rgb(82,82,82); margin-top:1px; margin-right:1px; -margin-left:0px; -margin-bottom:0px; -padding:0px; -min-width:55px; +margin-left:1px; +margin-bottom:2px; +padding:1px; +min-width:50px; } QTabBar::tab:selected{ @@ -536,7 +554,6 @@ margin-bottom:0px; padding:0px; } - QStatusBar::item{ color:0x222222; border:0px solid #484848; diff --git a/src/qss/common.qss b/src/qss/common.qss new file mode 100755 index 0000000..aadc551 --- /dev/null +++ b/src/qss/common.qss @@ -0,0 +1,97 @@ +.QPushButton{ +border-style:none; +border:1px solid #C0DCF2; +color:#000000; +background-color:#E1E1E1; +padding:3px; +min-height:15px; +min-width:50px; +border-radius:3px; +} + +.QPushButton:hover{ +background:qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 #F2F9FF,stop:1 #DAEFFF); +} + +QTabBar::tab{ + background-color:rgb(224,224,224); + margin-top:1px; + margin-right:1px; + margin-left:1px; + margin-bottom:2px; + padding:1px; + min-width:50px; +} + +QTabBar::tab:selected{ + background-color:rgb(255,255,255); + border-top:3px solid; + border-top-color:#FAAA3C; + margin-top:1px; + margin-right:1px; + margin-left:1px; + margin-bottom:2px; + padding:0px; +} +QTabBar::close-button{ + image: url(\":/notepad/closeTabButton.png\"); +} +QTabBar::close-button:hover{ + image: url(\":/notepad/closeTabButton_hover.png\"); +} + +QToolBar,QMessageBox,QHeaderView::section{ + background-color:rgba(255, 255, 255, 255); + border: none; + padding: 1px; +} + +QTabBar QToolButton[accessibleName="Scroll Left"]{border:0px;background-color:#F0F0F0;} + +QTabBar QToolButton[accessibleName="Scroll Right"]{border:0px;background-color:#F0F0F0;} + + +QTreeWidget{ + background-color:rgba(255, 255, 255, 255); + border:1px solid #C0DCF2; +} + +QTreeWidget::item +{ +height:22px; +} + +QTreeView::item::selected +{ +background-color:#00CCFF; +} + +QTreeView#resultTreeView{ + background-color:#444444; + border:1px solid #C0DCF2; +} + +QListWidget#filelistWidget{ + color:#ffffff; + background-color:#444444; + border:1px solid #C0DCF2; +} + +QMainWindow::separator +{ + height:1px; + margin: 0px; + padding: 0px; + background:#FF0000; +} + +QDockWidget{ + border:0px solid red; +} + +QDockWidget::title { + background:#f0f0f0; + padding-top:0px; +} + + diff --git a/src/qss/lightbluestyle.qss b/src/qss/lightbluestyle.qss index 99b5cf2..51dc707 100755 --- a/src/qss/lightbluestyle.qss +++ b/src/qss/lightbluestyle.qss @@ -3,7 +3,8 @@ border-style:none; border:1px solid #C0DCF2; color:#386487; padding:3px; -/*min-height:15px;*/ +min-height:15px; +min-width:50px; border-radius:3px; } @@ -41,9 +42,9 @@ background:qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 #DEF0FE,stop:1 } QToolBar,QMessageBox,QHeaderView::section{ - background-color:rgba(255, 255, 255, 255); - border: none; - padding: 1px; + background-color:rgba(255, 255, 255, 255); + border: none; + padding: 1px; } QComboBox,QLineEdit,QSpinBox{ @@ -146,7 +147,7 @@ QTabBar::close-button:hover{ /*设置垂直滚动条基本样式*/ QScrollBar:vertical { - width: 12px; + width: 15px; background: rgba(0,0,0,0%); margin: 0px,0px,0px,0px; /*留出9px给上面和下面的箭头*/ @@ -156,7 +157,7 @@ QScrollBar:vertical { } QScrollBar::handle:vertical { - width: 12px; + width: 15px; background: rgba(0,0,0,25%); /*滚动条两端变成椭圆 */ border-radius: 4px; @@ -164,7 +165,7 @@ QScrollBar::handle:vertical { } QScrollBar::handle:vertical:hover { - width: 12px; + width: 15px; /*鼠标放到滚动条上的时候,颜色变深*/ background: rgba(0,0,0,50%); border-radius: 4px; diff --git a/src/qss/myblack.qss b/src/qss/myblack.qss new file mode 100755 index 0000000..f3eda5f --- /dev/null +++ b/src/qss/myblack.qss @@ -0,0 +1,220 @@ +.QPushButton{ +border-style:none; +border:1px solid #C0DCF2; +color:#000000; +background-color:#E1E1E1; +padding:3px; +min-height:15px; +min-width:50px; +border-radius:3px; +} + +.QPushButton:hover{ +background:qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 #F2F9FF,stop:1 #DAEFFF); +} + +QTabBar::tab{ + background-color:rgb(224,224,224); + margin-top:1px; + margin-right:1px; + margin-left:1px; + margin-bottom:2px; + padding:1px; + min-width:50px; +} + +QTabBar::tab:selected{ + background-color:rgb(255,255,255); + border-top:3px solid; + border-top-color:#FAAA3C; + margin-top:1px; + margin-right:1px; + margin-left:1px; + margin-bottom:2px; + padding:0px; +} +QTabBar::close-button{ + image: url(\":/notepad/closeTabButton.png\"); +} +QTabBar::close-button:hover{ + image: url(\":/notepad/closeTabButton_hover.png\"); +} + +QToolBar,QMessageBox,QHeaderView::section{ + background-color:rgba(255, 255, 255, 255); + border: none; + padding: 1px; +} + +QTabBar QToolButton[accessibleName="Scroll Left"]{border:0px;background-color:#F0F0F0;} + +QTabBar QToolButton[accessibleName="Scroll Right"]{border:0px;background-color:#F0F0F0;} + + +QTreeWidget{ + background-color:rgba(255, 255, 255, 255); + border:1px solid #C0DCF2; +} + +QTreeWidget::item +{ +height:22px; +} + +QTreeView::item::selected +{ +background-color:#00CCFF; +} + +QTreeView#resultTreeView{ + background-color:#444444; + border:1px solid #C0DCF2; +} + +QListWidget#filelistWidget{ + color:#ffffff; + background-color:#444444; + border:1px solid #C0DCF2; +} + + +/*设置垂直滚动条基本样式*/ +QScrollBar:vertical { + width: 15px; + background: rgba(0,0,0,0%); + margin: 0px,0px,0px,0px; + /*留出9px给上面和下面的箭头*/ + padding-top: 9px; + padding-bottom: 9px; +} + +QScrollBar::handle:vertical { + width: 15px; + background: rgba(0,0,0,25%); + /*滚动条两端变成椭圆 */ + border-radius: 4px; + min-height: 20; +} + +QScrollBar::handle:vertical:hover { + width: 15px; + /*鼠标放到滚动条上的时候,颜色变深*/ + background: rgba(0,0,0,50%); + border-radius: 4px; + min-height: 20; +} + +/*这个应该是设置下箭头的,3.png就是箭头*/ +QScrollBar::add-line:vertical +{ + height: 9px; + width: 12px; + border-image: url(:/Resources/img/3.png); + subcontrol-position: bottom; +} + + +/*设置上箭头 */ +QScrollBar::sub-line:vertical +{ + height: 9px; + width: 12px; + border-image: url(:/Resources/img/1.png); + subcontrol-position: top; +} + +/*当鼠标放到下箭头上的时候 */ +QScrollBar::add-line:vertical:hover +{ + height: 9px; + width: 12px; + border-image: url(:/Resources/img/4.png); + subcontrol-position: bottom; +} + +/*当鼠标放到下箭头上的时候*/ +QScrollBar::sub-line:vertical:hover +{ + height: 9px; + width: 12px; + border-image: url(:/Resources/img/2.png); + subcontrol-position: top; +} + + + +/*当滚动条滚动的时候,上面的部分和下面的部分*/ +QScrollBar::sub-page { + background: rgba(0,0,0,10%); + border-radius: 4px; +} + +QScrollBar::add-page +{ + background: rgba(0,0,0,10%); + border-radius: 4px; +} + +/*设置水平滚动条基本样式*/ +QScrollBar:horizontal { + height: 10px; + background: rgba(0,0,0,0%); + margin: 0px,0px,0px,0px; + /*留出9px给上面和下面的箭头*/ + padding-left: 9px; + padding-right: 9px; +} + +QScrollBar::handle:horizontal { + height: 10px; + background: rgba(0,0,0,25%); + /*滚动条两端变成椭圆 */ + border-radius: 4px; + min-height: 20; +} + +QScrollBar::handle:horizontal:hover { + height: 10px; + /*鼠标放到滚动条上的时候,颜色变深*/ + background: rgba(0,0,0,50%); + border-radius: 4px; + min-height: 20; +} + +/*这个应该是设置下箭头的,3.png就是箭头*/ +QScrollBar::add-line:horizontal +{ + height: 10px; + width: 10px; + border-image: url(:/Resources/img/5.png); + subcontrol-position: right; +} + + +/*设置上箭头 */ +QScrollBar::sub-line:horizontal +{ + height: 10px; + width: 10px; + border-image: url(:/Resources/img/6.png); + subcontrol-position: left; +} + +QMainWindow::separator +{ + height:1px; + margin: 0px; + padding: 0px; + background:#FF0000; +} + +QDockWidget{ + border:0px solid red; +} + +QDockWidget::title { + background:#f0f0f0; + padding-top:0px; +} + + diff --git a/src/qss/mystyle.qss b/src/qss/mystyle.qss index f5616d5..4081705 100755 --- a/src/qss/mystyle.qss +++ b/src/qss/mystyle.qss @@ -1,3 +1,18 @@ +.QPushButton{ +border-style:none; +border:1px solid #C0DCF2; +color:#000000; +background-color:#E1E1E1; +padding:3px; +min-height:15px; +min-width:50px; +border-radius:3px; +} + +.QPushButton:hover{ +background:qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 #F2F9FF,stop:1 #DAEFFF); +} + QTabBar::tab{ background-color:rgb(224,224,224); margin-top:1px; @@ -51,128 +66,6 @@ QTreeView::item::selected background-color:#00CCFF; } -/*设置垂直滚动条基本样式*/ -QScrollBar:vertical { - width: 12px; - background: rgba(0,0,0,0%); - margin: 0px,0px,0px,0px; - /*留出9px给上面和下面的箭头*/ - padding-top: 9px; - padding-bottom: 9px; -} - -QScrollBar::handle:vertical { - width: 12px; - background: rgba(0,0,0,25%); - /*滚动条两端变成椭圆 */ - border-radius: 4px; - min-height: 20; -} - -QScrollBar::handle:vertical:hover { - width: 12px; - /*鼠标放到滚动条上的时候,颜色变深*/ - background: rgba(0,0,0,50%); - border-radius: 4px; - min-height: 20; -} - -/*这个应该是设置下箭头的,3.png就是箭头*/ -QScrollBar::add-line:vertical -{ - height: 9px; - width: 12px; - border-image: url(:/Resources/img/3.png); - subcontrol-position: bottom; -} - - -/*设置上箭头 */ -QScrollBar::sub-line:vertical -{ - height: 9px; - width: 12px; - border-image: url(:/Resources/img/1.png); - subcontrol-position: top; -} - -/*当鼠标放到下箭头上的时候 */ -QScrollBar::add-line:vertical:hover -{ - height: 9px; - width: 12px; - border-image: url(:/Resources/img/4.png); - subcontrol-position: bottom; -} - -/*当鼠标放到下箭头上的时候*/ -QScrollBar::sub-line:vertical:hover -{ - height: 9px; - width: 12px; - border-image: url(:/Resources/img/2.png); - subcontrol-position: top; -} - - - -/*当滚动条滚动的时候,上面的部分和下面的部分*/ -QScrollBar::sub-page { - background: rgba(0,0,0,10%); - border-radius: 4px; -} - -QScrollBar::add-page -{ - background: rgba(0,0,0,10%); - border-radius: 4px; -} - -/*设置水平滚动条基本样式*/ -QScrollBar:horizontal { - height: 10px; - background: rgba(0,0,0,0%); - margin: 0px,0px,0px,0px; - /*留出9px给上面和下面的箭头*/ - padding-left: 9px; - padding-right: 9px; -} - -QScrollBar::handle:horizontal { - height: 10px; - background: rgba(0,0,0,25%); - /*滚动条两端变成椭圆 */ - border-radius: 4px; - min-height: 20; -} - -QScrollBar::handle:horizontal:hover { - height: 10px; - /*鼠标放到滚动条上的时候,颜色变深*/ - background: rgba(0,0,0,50%); - border-radius: 4px; - min-height: 20; -} - -/*这个应该是设置下箭头的,3.png就是箭头*/ -QScrollBar::add-line:horizontal -{ - height: 10px; - width: 10px; - border-image: url(:/Resources/img/5.png); - subcontrol-position: right; -} - - -/*设置上箭头 */ -QScrollBar::sub-line:horizontal -{ - height: 10px; - width: 10px; - border-image: url(:/Resources/img/6.png); - subcontrol-position: left; -} - QMainWindow::separator { height:1px; diff --git a/src/qtlangset.cpp b/src/qtlangset.cpp index d4067f1..e88d132 100755 --- a/src/qtlangset.cpp +++ b/src/qtlangset.cpp @@ -11,7 +11,9 @@ #include #include #include -//#include +#include + +#include #include #if 0 @@ -37,43 +39,27 @@ enum LangType { }; #endif -static const QColor blackColor(Qt::black); -static const QColor lightColor(0xdedede); - -static const QColor blackColor1(0x0000ff); -static const QColor lightColor1(0xffaa00); - -//C++ע͵Ĭɫ -static const QColor blackColor2(0x007f00); -static const QColor lightColor2(0x009000); - -static const QColor blackColor3(0x7f7f00); -static const QColor lightColor3(0xfca287); - -static const QColor blackColor4(0x8000ff); -static const QColor lightColor4(0xffaa00); - -static const QColor blackColor5(0x007f7f); -static const QColor lightColor5(0xaaff7f); - -static const QColor blackColor6(0x7f007f); -static const QColor lightColor6(0x00ffff); - -QMap QtLangSet::s_darkColorMap; - -static void initDarkColorMap() -{ - if (QtLangSet::s_darkColorMap.isEmpty()) - { - QtLangSet::s_darkColorMap.insert(blackColor.name(), lightColor); - QtLangSet::s_darkColorMap.insert(blackColor1.name(), lightColor1); - QtLangSet::s_darkColorMap.insert(blackColor2.name(), lightColor2); - QtLangSet::s_darkColorMap.insert(blackColor3.name(), lightColor3); - QtLangSet::s_darkColorMap.insert(blackColor4.name(), lightColor4); - QtLangSet::s_darkColorMap.insert(blackColor5.name(), lightColor5); - QtLangSet::s_darkColorMap.insert(blackColor6.name(), lightColor6); - } -} +//static const QColor blackColor(Qt::black); +//static const QColor lightColor(0xdedede); +// +//static const QColor blackColor1(0x0000ff); +//static const QColor lightColor1(0xffaa00); +// +////C++ע͵Ĭɫ +//static const QColor blackColor2(0x007f00); +//static const QColor lightColor2(0xaaff7f); +// +//static const QColor blackColor3(0x7f7f00); +//static const QColor lightColor3(0xfca287); +// +//static const QColor blackColor4(0x8000ff); +//static const QColor lightColor4(0xffaa00); +// +//static const QColor blackColor5(0x007f7f); +//static const QColor lightColor5(0xaaff7f); +// +//static const QColor blackColor6(0x7f007f); +//static const QColor lightColor6(0x00ffff); QtLangSet::QtLangSet(QString initTag, QWidget *parent) : QMainWindow(parent), m_selectLexer(nullptr), m_selectStyleId(0), m_isStyleChange(false),m_isStyleChildChange(false), m_initShowLexerTag(initTag), m_previousSysLangItem(nullptr),m_isGlobelItem(false) @@ -83,7 +69,11 @@ QtLangSet::QtLangSet(QString initTag, QWidget *parent) initUserDefineLangList(); startSignSlot(); - initDarkColorMap(); + //initDarkColorMap(); + + m_themesId = StyleSet::getCurrentSytleId(); + m_lastThemesId = -1; + ui.mainThemesCbox->setCurrentIndex(m_themesId); } QtLangSet::~QtLangSet() @@ -122,8 +112,13 @@ void QtLangSet::startSignSlot() //ʼʹõQListWidget::currentItemChangedźţǷָźŴĪĴơ //QT5.12bugԻitemClickedź connect(ui.langListWidget, &QListWidget::itemClicked, this, &QtLangSet::slot_itemSelect); + connect(ui.langListWidget, &QListWidget::currentRowChanged, this, &QtLangSet::slot_langListCurRowChanged); + connect(ui.userLangListWidget, &QListWidget::itemClicked, this, &QtLangSet::slot_userLangItemSelect); + + connect(ui.styleListWidget, &QListWidget::itemClicked, this, &QtLangSet::slot_styleItemSelect); + connect(ui.styleListWidget, &QListWidget::currentRowChanged, this, &QtLangSet::slot_styleListCurRowChanged); connect(ui.boldCheckBox, &QCheckBox::stateChanged, this, &QtLangSet::slot_fontBoldChange); connect(ui.italicCheckBox, &QCheckBox::stateChanged, this, &QtLangSet::slot_fontItalicChange); @@ -181,9 +176,31 @@ void QtLangSet::slot_fontBoldChange(int state) if (m_isGlobelItem) { - if (ui.useGbFontBold->isChecked()) + if (ui.useGlobalFont->isVisible() && ui.useGbFontBold->isChecked()) { slot_useAlobalFontBold(true); + saveLangeSet(m_selectLexer); + } + else if (ui.useGlobalFont->isVisible() && !ui.useGbFontBold->isChecked()) + { + //ȫʽһʽ + saveLangeSet(m_selectLexer); + } + else if (!ui.useGlobalFont->isVisible()) + { + //ȫַǵһʽ޸ĵǰȫС + //ȫʽķǵһ + setGlobalFont(m_selectStyleId, m_curStyleData.font); + + //ȫʽһʽ + saveLangeSet(m_selectLexer); + + //ȫֵʽ֪ͨǰеı༭ȥ޸DZȫʽ + CCNotePad* pMainNote = dynamic_cast(parent()); + if (pMainNote != nullptr) + { + pMainNote->setGlobalFont(m_selectStyleId); + } } } else @@ -206,9 +223,29 @@ void QtLangSet::slot_fontItalicChange(int state) m_isStyleChange = true; if (m_isGlobelItem) { - if (ui.useGbFontItalic->isChecked()) + if (ui.useGlobalFont->isVisible() && ui.useGbFontItalic->isChecked()) { slot_useAlobalFontItalic(true); + saveLangeSet(m_selectLexer); + } + else if (ui.useGlobalFont->isVisible() && !ui.useGbFontItalic->isChecked()) + { + //ȫʽһʽ + saveLangeSet(m_selectLexer); + } + else if (!ui.useGlobalFont->isVisible()) + { + //ȫַǵһʽ޸ĵǰȫС + //ȫʽķǵһ + setGlobalFont(m_selectStyleId, m_curStyleData.font); + saveLangeSet(m_selectLexer); + + //ȫֵʽ֪ͨǰеı༭ȥ޸DZȫʽ + CCNotePad* pMainNote = dynamic_cast(parent()); + if (pMainNote != nullptr) + { + pMainNote->setGlobalFont(m_selectStyleId); + } } } else @@ -231,9 +268,29 @@ void QtLangSet::slot_fontUnderlineChange(int state) m_isStyleChange = true; if (m_isGlobelItem) { - if (ui.useGbFontUnderline->isChecked()) + if (ui.useGlobalFont->isVisible() && ui.useGbFontUnderline->isChecked()) { slot_useAlobalFontUnderline(true); + saveLangeSet(m_selectLexer); + } + else if (ui.useGlobalFont->isVisible() && !ui.useGbFontUnderline->isChecked()) + { + //ȫʽһʽ + saveLangeSet(m_selectLexer); + } + else if (!ui.useGlobalFont->isVisible()) + { + //ȫַǵһʽ޸ĵǰȫС + //ȫʽķǵһ + setGlobalFont(m_selectStyleId, m_curStyleData.font); + saveLangeSet(m_selectLexer); + + //ȫֵʽ֪ͨǰеı༭ȥ޸DZȫʽ + CCNotePad* pMainNote = dynamic_cast(parent()); + if (pMainNote != nullptr) + { + pMainNote->setGlobalFont(m_selectStyleId); + } } } else @@ -260,13 +317,45 @@ void QtLangSet::slot_fontSizeChange(int v) //qDebug() << m_curStyleData.font.family(); m_isStyleChange = true; m_selectLexer->setFont(m_curStyleData.font, m_selectStyleId); - if (ui.useGbFontSize->isChecked()) + + //ȫֵһʽ޸﷨ʽ + if (ui.useGlobalFont->isVisible() && ui.useGbFontSize->isChecked()) { slot_useAlobalFontSize(true); + saveLangeSet(m_selectLexer); + } + else if (ui.useGlobalFont->isVisible() && !ui.useGbFontSize->isChecked()) + { + //ȫʽһʽ + saveLangeSet(m_selectLexer); + } + else if (!ui.useGlobalFont->isVisible()) + { + //ȫַǵһʽ޸ĵǰȫС + //ȫʽķǵһ + setGlobalFont(m_selectStyleId, m_curStyleData.font); + saveLangeSet(m_selectLexer); + + //ȫֵʽ֪ͨǰеı༭ȥ޸DZȫʽ + CCNotePad* pMainNote = dynamic_cast(parent()); + if (pMainNote != nullptr) + { + pMainNote->setGlobalFont(m_selectStyleId); + } } } } - else if (!ui.modifyAllFont->isChecked()) + else + { + if (m_curStyleData.font.pointSize() != v) + { + m_curStyleData.font.setPointSize(v); + m_selectLexer->setFont(m_curStyleData.font, m_selectStyleId); + m_isStyleChange = true; + emit viewStyleChange(m_selectLexer->lexerTag(), m_selectStyleId, m_curStyleData.color, m_curStyleData.paper, m_curStyleData.font, true); + } + } + /*else if (!ui.modifyAllFont->isChecked()) { if (m_curStyleData.font.pointSize() != v) { @@ -302,9 +391,9 @@ void QtLangSet::slot_fontSizeChange(int v) saveCurLangSettings(); emit viewLexerChange(m_selectLexer->lexerTag()); } + }*/ } } -} void QtLangSet::getCurUseLexerTags(QVector& tag) @@ -323,6 +412,12 @@ void QtLangSet::updateAllLangeStyleWithGlobal(GLOBAL_STYLE_SET flag) for (int index = 0; index <= L_TXT; ++index) { + //GLOBAL棬ΪGLOBAL﷨ʽȫֵԷ + if (index == L_GLOBAL) + { + continue; + } + QsciLexer *pLexer = ScintillaEditView::createLexer(index); if (nullptr != pLexer) { @@ -451,10 +546,10 @@ void QtLangSet::restoreOriginLangAllStyle() //ֻrestoreOriginLangOneStyleе static void restoreLangFontFgColorToDarkStyle(QsciLexer *pLexer, int i) { - if (QtLangSet::s_darkColorMap.contains(pLexer->color(i).name())) - { - pLexer->setColor(QtLangSet::s_darkColorMap.value(pLexer->color(i).name()), i); - } + //if (QtLangSet::s_darkColorMap.contains(pLexer->color(i).name())) + //{ + // pLexer->setColor(QtLangSet::s_darkColorMap.value(pLexer->color(i).name()), i); + //} } //ֻrestoreOriginLangOneStyleе @@ -534,10 +629,10 @@ void QtLangSet::restoreOriginLangOneStyle(GLOBAL_STYLE_SET flag) oldClor = pOriginLexer->color(i); pLexer->setColor(oldClor, i); - if (BLACK_SE == StyleSet::getCurrentSytleId()) + /*if (BLACK_SE == StyleSet::getCurrentSytleId()) { restoreLangFontFgColorToDarkStyle(pLexer, i); - } + }*/ } break; @@ -546,10 +641,10 @@ void QtLangSet::restoreOriginLangOneStyle(GLOBAL_STYLE_SET flag) oldClor = pOriginLexer->paper(i); pLexer->setPaper(oldClor, i); - if (BLACK_SE == StyleSet::getCurrentSytleId()) + /*if (BLACK_SE == StyleSet::getCurrentSytleId()) { restoreLangPaperColorToDarkStyle(pLexer, i); - } + }*/ } break; default: @@ -581,7 +676,8 @@ void QtLangSet::slot_fontChange(const QFont &font) //ʱ÷ if (m_selectLexer != nullptr) { - if (!ui.modifyAllFont->isChecked()) + //ȫ޸ + if (m_isGlobelItem) { if (m_curStyleData.font != font) { @@ -589,21 +685,37 @@ void QtLangSet::slot_fontChange(const QFont &font) m_selectLexer->setFont(m_curStyleData.font, m_selectStyleId); m_isStyleChange = true; - if (m_isGlobelItem) + //޸ + if (ui.useGlobalFont->isVisible() && ui.useGbFont->isChecked()) { - if (ui.useGbFont->isChecked()) - { slot_useAlobalFont(true); + saveLangeSet(m_selectLexer); } - } - else + else if (ui.useGlobalFont->isVisible() && !ui.useGbFont->isChecked()) { - emit viewStyleChange(m_selectLexer->lexerTag(), m_selectStyleId, m_curStyleData.color, m_curStyleData.paper, m_curStyleData.font, true); + //ȫʽһʽ + saveLangeSet(m_selectLexer); + } + else if(!ui.useGlobalFont->isVisible()) + { + //ȫʽķǵһ + setGlobalFont(m_selectStyleId, m_curStyleData.font); + + //ȫʽһʽ + saveLangeSet(m_selectLexer); + + //ȫֵʽ֪ͨǰеı༭ȥ޸DZȫʽ + CCNotePad* pMainNote = dynamic_cast(parent()); + if (pMainNote != nullptr) + { + pMainNote->setGlobalFont(m_selectStyleId); } } } + } else { +#if 0 //ͳһ޸壬Сͷ񱣴治 QFont oldf = m_curStyleData.font; m_curStyleData.font = font; @@ -638,9 +750,19 @@ void QtLangSet::slot_fontChange(const QFont &font) saveCurLangSettings(); emit viewLexerChange(m_selectLexer->lexerTag()); } +#endif + if (m_curStyleData.font != font) + { + m_curStyleData.font.setFamily(font.family()); + m_selectLexer->setFont(m_curStyleData.font, m_selectStyleId); + m_isStyleChange = true; + + emit viewStyleChange(m_selectLexer->lexerTag(), m_selectStyleId, m_curStyleData.color, m_curStyleData.paper, m_curStyleData.font, true); + } } } +} void QtLangSet::initLangList() { @@ -730,6 +852,14 @@ void QtLangSet::slot_itemSelect(QListWidgetItem *item) } //qDebug() << item->text() << (previous ? previous->text() : 0); + //ǰⷢ˱仯Ҫ߸£ֹлûʱ + if (m_previousSysLangItem == item && (m_lastThemesId == m_themesId)) + { + return; + } + + ui.curThemes->setText(tr("Current themes : %1, language : %2").arg(StyleSet::getCurrentStyle()).arg(item->text())); + ui.langListWidget->scrollToItem(item); @@ -762,7 +892,6 @@ void QtLangSet::slot_itemSelect(QListWidgetItem *item) m_selectLexer = nullptr; } - int lexId = item->data(Qt::UserRole).toInt(); //ȫֵҪԴʱûκη @@ -770,27 +899,13 @@ void QtLangSet::slot_itemSelect(QListWidgetItem *item) { m_isGlobelItem = true; ui.stackedWidget->setCurrentIndex(1); - - //ȫ޸ģʽ£Ŀǰʱ޸е˵Ŀǰֻȫ޸ - ui.modiryAllColor->setChecked(false); - ui.modifyAllFont->setChecked(false); - ui.modiryAllColor->setEnabled(false); - ui.modifyAllFont->setEnabled(false); } else { m_isGlobelItem = false; ui.stackedWidget->setCurrentIndex(0); - if (!ui.modiryAllColor->isEnabled()) - { - ui.modiryAllColor->setEnabled(true); } - if (!ui.modifyAllFont->isEnabled()) - { - ui.modifyAllFont->setEnabled(true); - } - } QsciLexer *pLexer = ScintillaEditView::createLexer(lexId); if (nullptr != pLexer) @@ -830,6 +945,12 @@ void QtLangSet::slot_itemSelect(QListWidgetItem *item) ui.motherLangCb->setCurrentIndex(0); } +void QtLangSet::slot_langListCurRowChanged(int row) +{ + QListWidgetItem* current = ui.langListWidget->item(row); + slot_itemSelect(current); +} + //ĸģԣԷʾ void QtLangSet::displayUserMotherLangsStyle(QString langTagName, UserLangMother motherLang) { @@ -902,15 +1023,15 @@ void QtLangSet::slot_userLangItemSelect(QListWidgetItem *item) m_isGlobelItem = false; ui.stackedWidget->setCurrentIndex(0); - if (!ui.modiryAllColor->isEnabled()) + /*if (!ui.modiryAllColor->isEnabled()) { ui.modiryAllColor->setEnabled(true); } if (!ui.modifyAllFont->isEnabled()) { ui.modifyAllFont->setEnabled(true); + }*/ } - } m_previousSysLangItem = nullptr; @@ -959,28 +1080,112 @@ void QtLangSet::syncShowStyleItemToUI(QListWidgetItem *item) if (item != nullptr && m_selectLexer != nullptr) { int styleId = item->data(Qt::UserRole).toInt(); + + if (m_selectStyleId == styleId && (m_lastThemesId == m_themesId)) + { + return; + } + + if (!item->isSelected()) + { + item->setSelected(true); + } + + if (!ui.label_fc->isEnabled()) + { + ui.label_fc->setEnabled(true); + ui.toolButton->setEnabled(true); + } + if (!ui.label_bc->isEnabled()) + { + ui.label_bc->setEnabled(true); + ui.toolButton1->setEnabled(true); + } + if (!ui.fontComboBox->isEnabled()) + { + ui.fontComboBox->setEnabled(true); + ui.boldCheckBox->setEnabled(true); + ui.italicCheckBox->setEnabled(true); + ui.underlineCheckBox->setEnabled(true); + } + if (!ui.fontSpinBox->isEnabled()) + { + ui.fontSpinBox->setEnabled(true); + } + m_selectStyleId = styleId; QsciLexer::StyleData & sd = m_selectLexer->styleData(styleId); m_curStyleData = sd; setStyleShow(sd.font, sd.color, sd.paper); m_isStyleChange = false; + + //ȫ֣Ѳ޸ĵȫʽҵûѡ + if (m_isGlobelItem) + { + QsciLexerGlobal* pGlobalLexer = dynamic_cast(m_selectLexer); + if (pGlobalLexer != nullptr) + { + + int enableMask = pGlobalLexer->changeOperBit(styleId); + + if (!(enableMask & FG_BIT)) + { + ui.label_fc->setEnabled(false); + ui.toolButton->setEnabled(false); + } + if (!(enableMask & BG_BIT)) + { + ui.label_bc->setEnabled(false); + ui.toolButton1->setEnabled(false); +} + if (!(enableMask & FONT_BIT)) + { + ui.fontComboBox->setEnabled(false); + ui.boldCheckBox->setEnabled(false); + ui.italicCheckBox->setEnabled(false); + ui.underlineCheckBox->setEnabled(false); + } + if (!(enableMask & SIZE_BIT)) + { + ui.fontSpinBox->setEnabled(false); + } + } + + } } } //ǰķitem void QtLangSet::slot_styleItemSelect(QListWidgetItem *current) { -#if 0 - if (current != nullptr && m_selectLexer != nullptr) - { - int styleId = current->data(Qt::UserRole).toInt(); - m_selectStyleId = styleId; - QsciLexer::StyleData & sd = m_selectLexer->styleData(styleId); - m_curStyleData = sd; - setStyleShow(sd.font, sd.color, sd.paper); - m_isStyleChange = false; - } -#endif + qDebug() << "slot_styleItemSelect"; + syncShowStyleItemToUI(current); + + if (m_isGlobelItem && ui.styleListWidget->item(0) == current) + { + ui.useGlobalColor->setVisible(true); + ui.useGlobalFont->setVisible(true); + } + else + { + if (ui.useGlobalColor->isVisible()) + { + ui.useGlobalColor->setVisible(false); +} + if (ui.useGlobalFont->isVisible()) + { + ui.useGlobalFont->setVisible(false); + } + } + +} + +//ʹüл +void QtLangSet::slot_styleListCurRowChanged(int row) +{ + qDebug() << "slot_curRowChanged"; + QListWidgetItem* current = ui.styleListWidget->item(row); + slot_styleItemSelect(current); } void QtLangSet::fillForegroundColor(QColor& fcColor) @@ -1017,28 +1222,54 @@ void QtLangSet::setStyleShow(QFont& font, QColor& fcColor, QColor &bkColor) } -//ȡضԵ -bool QtLangSet::readLangSettings(QsciLexer *lexer, QString tag) +//ȡضԵãStyleId-1ȡǰ⣬ָStyleId +bool QtLangSet::readLangSettings(QsciLexer *lexer, QString tag, int StyleId) { - QString cfgPath = QString("notepad/userstyle/%1/%2").arg(StyleSet::getCurrentStyle()).arg(tag); + QString cfgPath = QString("notepad/userstyle/%1/%2").arg((StyleId == -1) ? StyleSet::getCurrentStyle() : StyleSet::getStyleName(StyleId)).arg(tag); QSettings qs(QSettings::IniFormat, QSettings::UserScope, cfgPath); if (QFile::exists(qs.fileName())) { return lexer->readSettings(qs); } + else//ӦüӸ߼걸ıûжȡûãӦôӱ׼Ŀȥԭʼ + { + return readLangOriginSettings(lexer, tag, StyleId); + } + + return false; +} + +//ȡضԵԭʼʽãStyleId-1ȡǰ⣬ָStyleId +bool QtLangSet::readLangOriginSettings(QsciLexer* lexer, QString tag, int StyleId) +{ + //ĬⲻҪȡڴѾ + if (StyleId == 0) + { + return true; + } + + //ĬƤ·ͬĿ¼themesĿ¼ + QString cfgPath = QString("%1/themes/%2/%3.ini").arg(QCoreApplication::applicationDirPath()).arg((StyleId == -1)?StyleSet::getCurrentStyle(): StyleSet::getStyleName(StyleId)).arg(tag); + QSettings qs(cfgPath, QSettings::IniFormat); + + //QSettings qs(QSettings::IniFormat, QSettings::UserScope, cfgPath); + if (QFile::exists(qs.fileName())) + { + return lexer->readSettings(qs); + } return false; } //һԵá -void QtLangSet::saveLangeSet(QsciLexer *lexer) +void QtLangSet::saveLangeSet(QsciLexer *lexer, int StyleId) { if (lexer != nullptr) { QString tag = lexer->lexerTag(); - QString cfgPath = QString("notepad/userstyle/%1/%2").arg(StyleSet::getCurrentStyle()).arg(tag); + QString cfgPath = QString("notepad/userstyle/%1/%2").arg((StyleId == -1) ? StyleSet::getCurrentStyle() : StyleSet::getStyleName(StyleId)).arg(tag); QSettings qs(QSettings::IniFormat, QSettings::UserScope, cfgPath); lexer->writeSettings(qs); @@ -1053,18 +1284,30 @@ bool QtLangSet::saveCurLangSettings() { saveLangeSet(m_selectLexer); m_isStyleChange = false; + ui.statusBar->showMessage(tr("Save Finished !"),10000); return true; } + ui.statusBar->showMessage(tr("Not change, no need save !"),10000); return false; } +bool QtLangSet::isUseGlobalFgColor() +{ + return ui.useGlobalColor->isVisible() && ui.useGbFc->isChecked(); +} + +bool QtLangSet::isUseGlobalBgColor() +{ + return ui.useGlobalColor->isVisible() && ui.useGbBc->isChecked(); +} + //޸ǰɫ void QtLangSet::slot_changeFgColor() { QColor color = QColorDialog::getColor(m_curStyleData.color, this, tr("Style Foreground Color")); if (color.isValid()) { - //ȫ޸ģԵз + //ȫ޸ if (m_isGlobelItem) { if (m_curStyleData.color != color) @@ -1076,17 +1319,33 @@ void QtLangSet::slot_changeFgColor() //ʱ÷ if (m_selectLexer != nullptr) { + //ʱһQsciLexerGlobal m_selectLexer->setColor(color, m_selectStyleId); } - if (ui.useGbFc->isChecked()) + //ֻڵһȫʽʱisUseGlobalFgColorΪtrueԵз + if (isUseGlobalFgColor()) { slot_useAlobalFgColor(true); } + else if(!ui.useGlobalColor->isVisible()) + { + //ȫʽķǵһ + setGlobalFgColor(m_selectStyleId, color); + + //ȫֵʽ֪ͨǰеı༭ȥ޸DZȫʽ + CCNotePad* pMainNote = dynamic_cast(parent()); + if (pMainNote != nullptr) + { + pMainNote->setGlobalFgColor(m_selectStyleId); } } - else if (!ui.modiryAllColor->isChecked()) + + } + + } + else { //ǰǰɫǷ仯 if (m_curStyleData.color != color) @@ -1104,34 +1363,42 @@ void QtLangSet::slot_changeFgColor() } } } - else + /*else if (!ui.modiryAllColor->isChecked()) { - //ȫɫ޸ - //ǰǰɫǷ仯 + ǰǰɫǷ仯 + if (m_curStyleData.color != color) + { m_curStyleData.color = color; fillForegroundColor(color); m_isStyleChange = true; - //ʱ÷ + ʱ÷ if (m_selectLexer != nullptr) { - /*int row = ui.styleListWidget->count(); + m_selectLexer->setColor(color, m_selectStyleId); - QListWidgetItem* item = nullptr; - - for (int i = 0; i < row; ++i) + emit viewStyleChange(m_selectLexer->lexerTag(), m_selectStyleId, color, m_curStyleData.paper, m_curStyleData.font, false); + } + } + }*/ + /*else { - item = ui.styleListWidget->item(i); - int styleId = item->data(Qt::UserRole).toInt();*/ - m_selectLexer->setColor(color, -1); - /*}*/ + ȫɫ޸ + ǰǰɫǷ仯 + m_curStyleData.color = color; + fillForegroundColor(color); + m_isStyleChange = true; + ʱ÷ + if (m_selectLexer != nullptr) + { + m_selectLexer->setColor(color, -1); saveCurLangSettings(); emit viewLexerChange(m_selectLexer->lexerTag()); } - + */ + // } } - } } @@ -1156,30 +1423,42 @@ void QtLangSet::slot_changeBkColor() m_selectLexer->setPaper(color, m_selectStyleId); } - if (ui.useGbBc->isChecked()) + if (isUseGlobalBgColor()) { slot_useAlobalBkColor(true); } + else if (!ui.useGlobalColor->isVisible()) + { + setGlobalBgColor(m_selectStyleId, color); + + //ȫֵʽ֪ͨǰеı༭ȥ޸DZȫʽ + CCNotePad* pMainNote = dynamic_cast(parent()); + if (pMainNote != nullptr) + { + pMainNote->setGlobalBgColor(m_selectStyleId); } } - else if (!ui.modiryAllColor->isChecked()) - { - //ǰǰɫǷ仯 - if (m_curStyleData.paper != color) - { - m_curStyleData.paper = color; - fillBackgroundColor(color); - m_isStyleChange = true; - - //ʱ÷ - if (m_selectLexer != nullptr) - { - m_selectLexer->setPaper(color, m_selectStyleId); - emit viewStyleChange(m_selectLexer->lexerTag(), m_selectStyleId, color, m_curStyleData.paper, m_curStyleData.font, false); - } - } } + + } + // else if (!ui.modiryAllColor->isChecked()) + // { + // //ǰǰɫǷ仯 + // if (m_curStyleData.paper != color) + // { + // m_curStyleData.paper = color; + // fillBackgroundColor(color); + // m_isStyleChange = true; + + // //ʱ÷ + // if (m_selectLexer != nullptr) + // { + // m_selectLexer->setPaper(color, m_selectStyleId); + // emit viewStyleChange(m_selectLexer->lexerTag(), m_selectStyleId, color, m_curStyleData.paper, m_curStyleData.font, false); + // } + // } + //} else { //ȫɫ޸ @@ -1230,27 +1509,27 @@ void QtLangSet::slot_reset() QFile::remove(qs.fileName()); } - //ǰɫ񣬻Ҫһ滻ɫ²۵ɫ - if (BLACK_SE == StyleSet::getCurrentSytleId()) - { - setLangFontFgColorToDarkStyle((LangType)m_selectLexer->lexerId(), m_selectLexer->lexerTag()); - } - //һҪȱ棬ΪselectInitLangTagܻ仯 - int row = ui.styleListWidget->currentRow(); + //ǿslot_itemSelectĽл + m_previousSysLangItem = nullptr; + selectInitLangTag(m_selectLexer->lexerTag()); //ֶˢUI QListWidgetItem* styleItem = ui.styleListWidget->item(row); + m_selectStyleId = -1; + syncShowStyleItemToUI(styleItem); emit viewLexerChange(m_selectLexer->lexerTag()); } else { + if (ui.useGlobalFont->isVisible()) + { //ȫãԶ if (QMessageBox::Yes != QMessageBox::question(this, tr("Reset All Style"), tr("Are you sure to reset All language sytle"))) { @@ -1258,12 +1537,6 @@ void QtLangSet::slot_reset() } restoreOriginLangAllStyle(); - //ǰɫ񣬻Ҫһ滻ɫ²۵ɫ - if (BLACK_SE == StyleSet::getCurrentSytleId()) - { - setAllLangFontFgColorToDarkStyle(); - } - previewAllGoblalChange(); //ֶˢUIȫĿǰֻһȫ @@ -1273,13 +1546,52 @@ void QtLangSet::slot_reset() delete m_selectLexer; } - //ǰڷܶȡԴָ;ǰȡԴ - m_selectLexer = ScintillaEditView::createLexer(L_GLOBAL,"",(BLACK_SE != StyleSet::getCurrentSytleId())); + m_selectLexer = ScintillaEditView::createLexer(L_GLOBAL); QListWidgetItem* styleItem = ui.styleListWidget->item(0); + m_selectStyleId = -1; + syncShowStyleItemToUI(styleItem); } + else + { + //ȫʽ + //һãǰ޸档⵱ǰĸոãֱ + m_isStyleChange = false; + + //ԶãҲɾ + QString cfgPath = QString("notepad/userstyle/%1/%2").arg(StyleSet::getCurrentStyle()).arg(m_selectLexer->lexerTag()); + + QSettings qs(QSettings::IniFormat, QSettings::UserScope, cfgPath); + if (QFile::exists(qs.fileName())) + { + QFile::remove(qs.fileName()); + } + + //һҪȱ棬ΪselectInitLangTagܻ仯 + + int row = ui.styleListWidget->currentRow(); + + //ǿslot_itemSelectĽл + m_previousSysLangItem = nullptr; + + //дALLglobalIJҲ + selectInitLangTag(tr("AllGlobal")); + + //ֶˢUI + QListWidgetItem* styleItem = ui.styleListWidget->item(row); + + m_selectStyleId = -1; + + syncShowStyleItemToUI(styleItem); + + //´ӼһδȫʽΪǰ汣ѾɾˣԼصǴġ + StyleSet::loadGolbalStyle(); + + updateThemes(); +} + } } } @@ -1387,128 +1699,214 @@ void QtLangSet::slot_useAlobalFontItalic(bool check) //ĬԷIJɫ滻Ϊɫ۵ɫ //ǿԴԶԵġ -void QtLangSet::setLangFontFgColorToDarkStyle(LangType langId, QString tag) -{ - //QColor blackColor(Qt::black); - //QColor lightColor(0xdedede); - - //QColor blackColor1(0x0000ff); - //QColor lightColor1(0xffaa00); - - - ////C++ע͵Ĭɫ - //QColor blackColor2(0x007f00); - //QColor lightColor2(0x009000); - - //QColor blackColor3(0x7f7f00); - //QColor lightColor3(0xfca287); - - - //QColor blackColor4(0x8000ff); - //QColor lightColor4(0xffaa00); - - //עɫvoid StyleSet::setBlackStyle()бһ - //QColor bkPaperColor(0, 0, 0); - - QsciLexer *pLexer = ScintillaEditView::createLexer(langId, tag); - if (nullptr != pLexer) - { - for (int i = 0; i <= 255; ++i) - { - if (!pLexer->description(i).isEmpty()) - { - /*if (blackColor == pLexer->color(i)) - { - pLexer->setColor(lightColor, i); - } - else if (blackColor1 == pLexer->color(i)) - { - pLexer->setColor(lightColor1, i); - } - else if (blackColor2 == pLexer->color(i)) - { - pLexer->setColor(lightColor2, i); - } - else if (blackColor3 == pLexer->color(i)) - { - pLexer->setColor(lightColor3, i); - } - else if (blackColor4 == pLexer->color(i)) - { - pLexer->setColor(lightColor4, i); - }*/ - - if (QtLangSet::s_darkColorMap.contains(pLexer->color(i).name())) - { - pLexer->setColor(QtLangSet::s_darkColorMap.value(pLexer->color(i).name()), i); - } - - //Ҳɰɫ - if (StyleSet::foldbgColor != pLexer->paper(i)) - { - pLexer->setPaper(StyleSet::foldbgColor, i); - } - } - } - //ĬֽɫQPaletteһ¡Ϊɫɫ䱳QPaletteһҪһ - pLexer->setDefaultPaper(StyleSet::foldbgColor); - saveLangeSet(pLexer); - delete pLexer; - } - } - -//Ѱɫϵ治׿ɫ滻һ¡ĬзģĬϷɫϵġ -//ѷ0x000000壬0xdedede -//0x0000ffɫ0xffff00 -//ûдԶԡ -void QtLangSet::setAllLangFontFgColorToDarkStyle() -{ - initDarkColorMap(); - - for (int index = 0; index <= L_TXT; ++index) - { - setLangFontFgColorToDarkStyle((LangType)index); - } - } - -//鵱ǰǷѾڰɫ -bool QtLangSet::isExistDarkLangSetings() -{ - QString cfgPath = QString("notepad/userstyle/black/AllGlobal"); - QSettings qs(QSettings::IniFormat, QSettings::UserScope, cfgPath); - return QFile::exists(qs.fileName()); - } - -////ѷ0xdedede壬0x000000 -//void QtLangSet::setAllLangFontFgColorToLightStyle() +//void QtLangSet::setLangFontFgColorToDarkStyle(LangType langId, QString tag) //{ // QColor blackColor(Qt::black); // QColor lightColor(0xdedede); // -// QColor blackColor1(0xffaa00); -// QColor lightColor1(0x0000ff); +// QColor blackColor1(0x0000ff); +// QColor lightColor1(0xffaa00); // -// for (int index = 0; index <= L_TXT; ++index) -// { -// QsciLexer *pLexer = ScintillaEditView::createLexer(index); +// +// //C++ע͵Ĭɫ +// QColor blackColor2(0x007f00); +// QColor lightColor2(0x009000); +// +// QColor blackColor3(0x7f7f00); +// QColor lightColor3(0xfca287); +// +// +// QColor blackColor4(0x8000ff); +// QColor lightColor4(0xffaa00); +// +// עɫvoid StyleSet::setBlackStyle()бһ +// QColor bkPaperColor(0, 0, 0); +// +// QsciLexer *pLexer = ScintillaEditView::createLexer(langId, tag); // if (nullptr != pLexer) // { // for (int i = 0; i <= 255; ++i) // { // if (!pLexer->description(i).isEmpty()) // { -// if (lightColor == pLexer->color(i)) +// /*if (blackColor == pLexer->color(i)) // { -// pLexer->setColor(blackColor, i); +// pLexer->setColor(lightColor, i); // } // else if (blackColor1 == pLexer->color(i)) // { // pLexer->setColor(lightColor1, i); // } +// else if (blackColor2 == pLexer->color(i)) +// { +// pLexer->setColor(lightColor2, i); +// } +// else if (blackColor3 == pLexer->color(i)) +// { +// pLexer->setColor(lightColor3, i); +// } +// else if (blackColor4 == pLexer->color(i)) +// { +// pLexer->setColor(lightColor4, i); +// }*/ +// +// if (QtLangSet::s_darkColorMap.contains(pLexer->color(i).name())) +// { +// pLexer->setColor(QtLangSet::s_darkColorMap.value(pLexer->color(i).name()), i); +// } +// +// Ҳɰɫ +// if (StyleSet::foldbgColor != pLexer->paper(i)) +// { +// pLexer->setPaper(StyleSet::foldbgColor, i); // } // } +// } +// ĬֽɫQPaletteһ¡Ϊɫɫ䱳QPaletteһҪһ +// pLexer->setDefaultPaper(StyleSet::foldbgColor); // saveLangeSet(pLexer); // delete pLexer; // } // } + +//Ѱɫϵ治׿ɫ滻һ¡ĬзģĬϷɫϵġ +//ѷ0x000000壬0xdedede +//0x0000ffɫ0xffff00 +//ûдԶԡ +//void QtLangSet::setAllLangFontFgColorToDarkStyle() +//{ +// initDarkColorMap(); +// +// for (int index = 0; index <= L_TXT; ++index) +// { +// setLangFontFgColorToDarkStyle((LangType)index); +// } //} + + +//Ĭģ崴һûԷļ +void QtLangSet::createOneLangStyleFromThemes(int styleId, LangType langId, QString tag) +{ + if (langId == L_GLOBAL) + { + qDebug("global call"); + } + //ָԭʼģжȡһ + QsciLexer* pLexer = ScintillaEditView::createLexer(langId, tag, true, styleId); + if (nullptr != pLexer) + { + saveLangeSet(pLexer, styleId); + delete pLexer; + } +} + +//ԭʼģУһûļ +void QtLangSet::createUserStyleFormThemes(int styleId) +{ + for (int index = 0; index <= L_TXT; ++index) + { + createOneLangStyleFromThemes(styleId, (LangType)index); + } +} + +//鵱ǰǷѾڰɫ +//bool QtLangSet::isExistDarkLangSetings() +//{ +// QString cfgPath = QString("notepad/userstyle/black/AllGlobal"); +// QSettings qs(QSettings::IniFormat, QSettings::UserScope, cfgPath); +// return QFile::exists(qs.fileName()); +//} + +//鵱ǰǷѾ +bool QtLangSet::isExistThemesSetings(int styleId) +{ + QString cfgPath = QString("notepad/userstyle/%1/AllGlobal").arg(StyleSet::getStyleName(styleId)); + QSettings qs(QSettings::IniFormat, QSettings::UserScope, cfgPath); + return QFile::exists(qs.fileName()); +} + +//ǰⷢ仯 +void QtLangSet::on_themesChange(int styleIndex) +{ + //һʱֹʼûгʼ⣬ʼһisExistThemesSetings + if (m_themesId == styleIndex && isExistThemesSetings(styleIndex)) + { + return; + } + ui.statusBar->showMessage(tr("themes changing, please waiting ..."), 5000); + + m_themesId = styleIndex; + + //иϣҪQsciLexerĵǰ⡣ֻĬϸķ + //Ĭ⣬ʼȫĬʽ + + QsciLexer::setCurThemes(m_themesId); + + //ãģ濽һݳ + if (!isExistThemesSetings(styleIndex)) + { + createUserStyleFormThemes(styleIndex); + } + + StyleSet::setCurrentStyle(styleIndex); + + NddSetting::updataKeyValueFromNumSets(SKIN_KEY, m_themesId); + + //Ҫʱлǰ⣬Ԥɫ + updateThemes(); + + //һҪõǰ༭﷨ + previewAllGoblalChange(); + + int row = ui.langListWidget->currentRow(); + + //ֶˢUI + QListWidgetItem* styleItem = ui.langListWidget->item(row); + + slot_itemSelect(styleItem); + + m_lastThemesId = m_themesId; + + ui.statusBar->showMessage(tr("themes changed finished ..."), 5000); +} + +//µǰ༭ʽ +void QtLangSet::updateThemes() +{ + CCNotePad* pMainNote = dynamic_cast(parent()); + if (pMainNote != nullptr) + { + pMainNote->updateThemes(); + } +} + +//ȫֵǰһIJһ +void QtLangSet::setGlobalFgColor(int style, QColor color) +{ + One_Stype_Info* pStyle = &StyleSet::s_global_style->global_style; + + if (pStyle[style].fgColor != color) + { + pStyle[style].fgColor = color; + } +} + +void QtLangSet::setGlobalBgColor(int style, QColor color) +{ + One_Stype_Info* pStyle = &StyleSet::s_global_style->global_style; + + if (pStyle[style].bgColor != color) + { + pStyle[style].bgColor = color; + } +} + +void QtLangSet::setGlobalFont(int style, QFont font) +{ + One_Stype_Info* pStyle = &StyleSet::s_global_style->global_style; + + if (pStyle[style].font != font) + { + pStyle[style].font = font; + } +} diff --git a/src/qtlangset.h b/src/qtlangset.h index 230dbab..04e44d6 100755 --- a/src/qtlangset.h +++ b/src/qtlangset.h @@ -6,6 +6,9 @@ #include #include "ui_qtlangset.h" #include "rcglobal.h" +#include "Qsci/qsciscintilla.h" +#include "Scintilla.h" +#include "SciLexer.h" class QsciLexer; @@ -20,6 +23,8 @@ enum GLOBAL_STYLE_SET { GLOBAL_BK_COLOR, }; + + class QtLangSet : public QMainWindow { Q_OBJECT @@ -28,12 +33,14 @@ public: QtLangSet(QString initTag, QWidget *parent = nullptr); ~QtLangSet(); - static void setAllLangFontFgColorToDarkStyle(); - static bool isExistDarkLangSetings(); + /*static void setAllLangFontFgColorToDarkStyle();*/ + //static bool isExistDarkLangSetings(); void selectInitLangTag(QString initLangTag); - static bool readLangSettings(QsciLexer * lexer, QString tag); + static bool readLangSettings(QsciLexer * lexer, QString tag, int StyleId = -1); + static bool readLangOriginSettings(QsciLexer* lexer, QString tag, int StyleId=-1); private: - static void setLangFontFgColorToDarkStyle(LangType langId, QString tag=""); + //static void setLangFontFgColorToDarkStyle(LangType langId, QString tag=""); + static void createOneLangStyleFromThemes(int styleId, LangType langId, QString tag = ""); void startSignSlot(); @@ -52,7 +59,11 @@ protected: private slots: void slot_itemSelect(QListWidgetItem * item); + void slot_langListCurRowChanged(int row); + void slot_styleItemSelect(QListWidgetItem * item); + void slot_styleListCurRowChanged(int row); + void slot_saveClick(); void slot_reset(); void slot_changeFgColor(); @@ -71,7 +82,7 @@ private slots: void slot_useAlobalFontBold(bool); void slot_useAlobalFontUnderline(bool); void slot_useAlobalFontItalic(bool); - + void on_themesChange(int index); @@ -80,7 +91,7 @@ private: bool readLangSetFile(QString langName, QString & keyword, QString & motherLang, QString & extTypes); void initUserDefineLangList(); void setStyleShow(QFont & font, QColor& fcColor, QColor &bkColor); - static void saveLangeSet(QsciLexer * lexer); + static void saveLangeSet(QsciLexer * lexer, int styleId=-1); bool saveCurLangSettings(); void fillForegroundColor(QColor & fcColor); void fillBackgroundColor(QColor & bkColor); @@ -93,7 +104,17 @@ private: void getCurUseLexerTags(QVector& tag); void enableFontChangeSensitive(bool isSensitive); + void updateThemes(); + bool isUseGlobalFgColor(); + bool isUseGlobalBgColor(); + + void setGlobalFgColor(int style, QColor color); + void setGlobalBgColor(int style, QColor color); + void setGlobalFont(int style, QFont font); + + bool isExistThemesSetings(int styleId); + void createUserStyleFormThemes(int styleId); private: Ui::QtLangSetClass ui; @@ -116,7 +137,11 @@ private: //是否是全局修改项 bool m_isGlobelItem; + int m_themesId; + + int m_lastThemesId; + public: - //黑色模式下不显眼的颜色,替换到显眼颜色 - static QMap s_darkColorMap; + ////黑色模式下不显眼的颜色,替换到显眼颜色 + //static QMap s_darkColorMap; }; diff --git a/src/qtlangset.ui b/src/qtlangset.ui index 3c6b1e6..4100aba 100755 --- a/src/qtlangset.ui +++ b/src/qtlangset.ui @@ -6,8 +6,8 @@ 0 0 - 983 - 728 + 1029 + 660 @@ -18,8 +18,157 @@ :/Resources/edit/global/ndd.ico:/Resources/edit/global/ndd.ico - + + + + + + Qt::Horizontal + + + QSizePolicy::Preferred + + + + 40 + 20 + + + + + + + + Select Main: + + + + + + + + 200 + 0 + + + + + Default(stylers.xml) + + + + + Bespin + + + + + Black board + + + + + Blue Light + + + + + Choco + + + + + DansLeRuSH-Dark + + + + + Deep Black + + + + + Lavender + + + + + HotFudgeSundae + + + + + Misty Rose + + + + + Mono Industrial + + + + + Monokai + + + + + Obsidian + + + + + Plastic Code Wrap + + + + + Ruby Blue + + + + + Twilight + + + + + Vibrant Ink + + + + + Yellow Rice + + + + + + + + TextLabel + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + @@ -38,7 +187,7 @@ - 220 + 220 16777215 @@ -61,7 +210,7 @@ - 220 + 220 150 @@ -96,365 +245,379 @@ - - - - - Color - - - - - - - - Foreground: - - - - - - - - 0 - 0 - - - - - 32 - 32 - - - - TextLabel - - - - - - - Select - - - - - - - All Style - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - background: - - - - - - - - 0 - 0 - - - - - 32 - 32 - - - - Same As Theme - - - - - - - Select - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - + - - - Font - - - - - - - - Name: - - - - - - - - - - - - - - - - Bold - - - - - - - Italic - - - - - - - Underline - - - - - - - - - + + + + + + + Color + + - - - Font Size: - - - - - - - 1 + + + + + Foreground: + + + + + + + + 0 + 0 + + + + + 32 + 32 + + + + TextLabel + + + + + + + Select + + + + + + + + + + + background: + + + + + + + + 0 + 0 + + + + + 32 + 32 + + + + Same As Theme + + + + + + + Select + + + + + + + + + + + + Use Global Color + + + + + + Use Global Foreground Color - - - - - - - All Style - + + + + + true + + + Use Global Background Color + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + Font + + + + + + + + Name: + + + + + + + + + + + + + + + + Bold + + + + + + + Italic + + + + + + + Underline + + + + + + + + + + + + + Font Size: + + + + + + + 1 + + + + + + + + + + + + + + + + 1 + + + + + 0 + + + 0 + + + + + Keyword And Mother + + + + 0 + + + 0 + + + + + true + + + + + + + + + Mother Language: + + + + + + + false + + + + None + + + + + Cpp + + + + + + + + + + + + Ext File Type: + + + + + + + true + + + + + + + + + - - - - - - - + + + + 0 + + + 0 + + + + + Global Style Font + + + + + + Use Global Font + + + + + + + Use Global FontSize + + + + + + + Use Global Bold Font + + + + + + + Use Global Italic Font + + + + + + + Use Global Underline Font + + + + + + + + + + + + + - - - 1 - - - - - - - Keyword And Mother - - - - - - true - - - - - - - - - Mother Language: - - - - - - - false - - - - None - - - - - Cpp - - - - - - - - - - - - Ext File Type: - - - - - - - true - - - - - - - - - - - - - - - - Global Style Set + + + + + reset + + + + + + + Save + + + + + + + Close - - - - - Use Global Foreground Color - - - - - - - true - - - Use Global Background Color - - - - - - - Use Global Font - - - - - - - Use Global FontSize - - - - - - - Use Global Bold Font - - - - - - - Use Global Italic Font - - - - - - - Use Global Underline Font - - - - - - - - - - - - - reset - - - - - - - Save - - - - - - - Close - - @@ -467,7 +630,7 @@ 0 0 - 983 + 1029 23 @@ -494,8 +657,8 @@ close() - 971 - 694 + 1016 + 625 709 @@ -510,8 +673,8 @@ slot_saveClick() - 857 - 694 + 843 + 625 575 @@ -526,8 +689,8 @@ slot_changeFgColor() - 832 - 92 + 725 + 123 462 @@ -542,8 +705,8 @@ slot_reset() - 743 - 694 + 669 + 625 814 @@ -558,8 +721,8 @@ slot_useAlobalFgColor(bool) - 803 - 347 + 726 + 225 491 @@ -574,8 +737,8 @@ slot_useAlobalFont(bool) - 803 - 435 + 1009 + 291 491 @@ -590,8 +753,8 @@ slot_useAlobalFontBold(bool) - 803 - 523 + 1009 + 413 491 @@ -606,8 +769,8 @@ slot_useAlobalFontItalic(bool) - 803 - 567 + 1009 + 474 491 @@ -622,8 +785,8 @@ slot_useAlobalFontUnderline(bool) - 803 - 611 + 1009 + 535 491 @@ -638,8 +801,8 @@ slot_useAlobalFontSize(bool) - 803 - 479 + 1009 + 352 491 @@ -654,8 +817,8 @@ slot_useAlobalBkColor(bool) - 803 - 391 + 726 + 247 491 @@ -670,8 +833,8 @@ slot_changeBkColor() - 829 - 123 + 725 + 163 491 @@ -679,6 +842,22 @@ + + mainThemesCbox + currentIndexChanged(int) + QtLangSetClass + on_themesChange(int) + + + 221 + 55 + + + 390 + 635 + + + slot_saveClick() @@ -692,5 +871,6 @@ slot_useAlobalFontUnderline(bool) slot_useAlobalFontItalic(bool) slot_useAlobalBkColor(bool) + on_themesChange(int) diff --git a/src/rcglobal.cpp b/src/rcglobal.cpp index 6d49907..6cfe791 100755 --- a/src/rcglobal.cpp +++ b/src/rcglobal.cpp @@ -2,6 +2,7 @@ #include #include #include +#include QString s_userLangDirPath; @@ -18,3 +19,31 @@ QString getUserLangDirPath() } return s_userLangDirPath; } + +void showFileInExplorer(QString path) +{ + QString cmd; + +#ifdef _WIN32 + path = path.replace("/", "\\"); + cmd = QString("explorer.exe /select,%1").arg(path); +#endif + +#ifdef ubu + path = path.replace("\\", "/"); + cmd = QString("nautilus %1").arg(path); +#endif + +#ifdef uos + path = path.replace("\\", "/"); + cmd = QString("dde-file-manager %1").arg(path); +#endif + +#if defined(Q_OS_MAC) + path = path.replace("\\", "/"); + cmd = QString("open -R %1").arg(path); +#endif + + QProcess process; + process.startDetached(cmd); +} diff --git a/src/rcglobal.h b/src/rcglobal.h index cf86043..404bde0 100755 --- a/src/rcglobal.h +++ b/src/rcglobal.h @@ -5,7 +5,7 @@ #include #include -static const char* VersionStr = "v1.19.2"; +static const char* VersionStr = "v1.21.0"; #define CMP_CODE_NOEQUAL @@ -137,3 +137,24 @@ enum UserLangMother }; QString getUserLangDirPath(); + +//在这定义一次即可。 +//#define uos 1 + +#ifdef Q_OS_WIN +#undef uos +#endif + +#ifdef ubu +#undef uos +#endif + +#ifdef uos +#undef ubu +#endif + +#ifdef Q_OS_MAC +#undef uos +#endif + +void showFileInExplorer(QString path); diff --git a/src/realcompare_zh.qm b/src/realcompare_zh.qm index c6e69bd..3c8d99c 100755 Binary files a/src/realcompare_zh.qm and b/src/realcompare_zh.qm differ diff --git a/src/realcompare_zh.ts b/src/realcompare_zh.ts index 6bc064f..bd1dc2d 100755 --- a/src/realcompare_zh.ts +++ b/src/realcompare_zh.ts @@ -67,6 +67,214 @@ 关闭 + + BatchFindReplace + + + $1 has no find match work item + %1 没有对应的查找匹配项! + + + Max find key word 10000 ! + 最多支持10000条关键字! + + + + Please input find keyword ! + 请输入批量查找的关键字! + + + Batch Find Finished! + 批量查找完成! + + + + Max find key word 20000 ! + 最多支持10000条关键字! {20000 ?} + + + + + total %1 keyword, please wait ... + + + + + Batch Find Finished! total %1 found. + + + + + Batch Replace Finished, total Replace %1 times ! + 批量替换完成,一共替换 %1 处! + + + + Save File As ... + 另存为文件 ... + + + + Export File finished ! + 导出配置文件成功 ! + + + + No Content to Export ! + 没有内容以供导出! + + + + Batch Mark Finished, total Mark %1 times ! + 批量标记完成,一共标记 %1 处! + + + + BatchFindReplaceClass + + + + BatchFindReplace + 批量查找替换 + + + + + Enter multiple find keywords, separated by blank characters + 请输入多个查找关键字,使用空白符分隔开 + + + + + Enter multiple Replace keywords, separated by blank characters + 请输入多个替换关键字,使用空白符分隔开 + + + + + Keyword + 关键词 + + + + + + + Replace + 替换 + + + + + Fresh + 刷新 + + + + + swap + 交换 + + + + + Find + 查找 + + + + + Mark + 标记 + + + + + ClearMark + 清除标记 + + + + + Import + 导入 + + + + + Export + 导出 + + + + BigFileMessageClass + + + + BigFileMessage + 大文件打开方式 + + + + + TextLabel + + + + + + Open Mode + 打开方式 + + + + + Text Mode + 文本模式 + + + + + Open directly in text mode.May be slow, Need wait. + 直接以普通文本打开,注意:可能比较慢或卡顿,需要等待。(不推荐) + + + + + Big Text + 大文本模式 + + + + + Read only open, load in blocks, and turn pages manually. + 分块只读打开大文件,速度快,需要手动进行前后翻页。(推荐) + + + + + Hex Bin + 二进制模式 + + + + + Binary Open,load in blocks, and turn pages manually. + 二进制打开,速度快,需要手动进行前后翻页。 + + + + + Ok + 确定 + + + + + Cancel + 取消 + + CCNotePad @@ -79,7 +287,7 @@ - + Format Conversion 格式转换 @@ -93,7 +301,7 @@ - + Display symbols 显示符号 @@ -102,130 +310,130 @@ 编码 - - + + Language 语言 - - + + P - - - - + + + + C - - + + J - - - - + + + + R - - + + H - - + + M - - + + B - - + + I - - + + N - - + + A - - + + S - - + + V - - + + L - - + + T - - + + F - - - - - - + + + + + + D - - + + O - - + + E - - + + G @@ -234,14 +442,12 @@ 设置 - - Style - 皮肤风格 + 皮肤风格 - - + + About 关于 @@ -250,389 +456,387 @@ 对比 + + Recently - 最近对比 + 最近对比 - - Dir ... - 目录... + 目录... - - File ... - 文件... + 文件... - - + + New 新建 - - + + Open ... 打开 - - + + Ctrl+O - - + + Save 保存 - - + + Ctrl+S - - + + Save As ... 另存为 - - + + Ctrl+Alt+S - - - - + + + + Close 关闭 - - + + Ctrl+W - - + + Exit 退出 - - + + Ctrl+Q - - - + + + Close All 关闭所有 - - + + Ctrl+Shift+W - - - + + + Undo 撤销 - - + + Ctrl+Z - - - + + + Redo 重做 - - + + Ctrl+Y - - - + + + Cut 剪切 - - + + Ctrl+X - - + + Copy 拷贝 - - + + Ctrl+C - - - + + + Paste 粘贴 - - + + Ctrl+V - - + + Select All 全选 - - + + Ctrl+A - - + + Windows(CR+LF) - - + + Unix(LF) - - + + Mac(CR) - - - + + + Find 查找 - - + + Ctrl+F - - - + + + Replace 替换 - - + + Go line 跳转 - - + + Ctrl+G - - + + Show spaces/tabs 显示空格 - - + + Show end of line 显示行尾 - - + + Show all 显示所有 - - + + Encode in GBK 编码 GBK - - + + Encode in UTF8 编码 UTF8 - - + + Encode in UTF8-BOM 编码 UTF8-BOM - - + + Encode in UCS-2 BE BOM 编码 UCS-2 BE BOM - - + + Encode in UCS-2 LE BOM 编码 UCS-2 LE BOM - - + + Convert to GBK 转换为 GBK 编码 - - + + Convert to UTF8 转换为 UTF8 编码 - - + + Convert to UTF8-BOM 转换为 UTF8-BOM 编码 - - + + Convert to UCS-2 BE BOM 转换为 UCS-2 BE BOM 编码 - - + + Convert to UCS-2 LE BOM 转换为 UCS-2 LE BOM 编码 - - + + Batch convert 批量转换编码 - - + + Options 选项 - - + + BugFix 问题反馈 - - + + Donate 捐赠作者 - - + + Default 默认 - - + + LightBlue 亮蓝 - - + + ThinBlue 淡蓝 - - + + RiceYellow 纸黄 - - - - + + + + Yellow 黄色 - - + + Silver 银色 - - + + LavenderBlush 淡紫红 - - + + MistyRose 浅玫瑰色 - - + + English 英文 - - + + Chinese 中文 @@ -641,1102 +845,1144 @@ 捐赠软件 - - + + TXT - - + + Search Result 查找结果 - - - - + + + + test - - + + go - - + + File compare 文件对比 - + notepad-- - + File(&F) 文件(&F) - + Edit(&E) 编辑(&E) - + Blank CharOperate 空白字符操作 - + Convert Case to 大小写转换 - + Line Operations 行编辑 - + Search(&S) 查找(&S) - + Book Mark 书签 - + Mark Color 标记颜色... - + View(&V) 视图(&V) - + Icon Size 图标大小 - - + + Encoding(&N) 编码(&N) - - + + Other 其它编码 - - + + Convert to Other 转换为其它编码 - - + + Language(&L) 语言(&L) - - + + Set(&T) 设置(&T) - - + Format Language 格式化语言 - - + + Feedback 反馈问题 - - + + Compare(&C) 对比(&C) - - Recently(&R) - 最近对比(&R) + 最近对比(&R) - - + + Ctrl+T - - + + Ctrl+H - - + + Dir compare 目录对比 - - + + XML - - + + YAML - - + + Php - - + + C++ - - + + C# - - + + Objective C - - + + Java - - + + RC - - + + HTML - - + + Makefile - - + + Pascal - - + + Batch - - + + ini - - + + Nfo - - + + Asp - - + + Sql - - + + Virsual Basic - - + + JavaScript - - + + Css - - + + Perl - - + + Python - - + + Lua - - + + Tex - - + + Fortran - - + + Shell - - + + ActionScript - - + + NSIS - - + + Tcl - - + + Lisp - - + + Scheme - - + + Assembly - - + + Diff - - + + Properties file - - + + PostScript - - + + Ruby - - + + Smalltalk - - + + VHDL - - + + AutoIt - - + + CMake - - + + PowerShell - - + + Jsp - - + + CoffeeScript - - + + BaanC - - + + S-Record - - + + TypeScript - - + + Visual Prolog - - + + Txt2tags - - + + Rust - - + + Registry - - + + REBOL - - + + OScript - - + + Nncrontab - - + + Nim - - + + MMIXAL - - + + LaTex - - + + Forth - - + + ESCRIPT - - + + Erlang - - + + Csound - - + + FreeBasic - - + + BlitzBasic - - + + PureBasic - - + + AviSynth - - + + ASN.1 - - + + Swift - - + + Intel HEX - - + + Fortran77 - - + + Edifact - - - - + + + + MarkDown - - + + Octave - - + + Po - - + + Pov - - + + json - - + + AVS - - + + Bash - - + + IDL - - + + Matlab - - + + Spice - - + + Verilog - - + + Register 注册版本 - - + + Language Format 编程语言格式 - - + + Open In Text 以文本模式打开 - - + + Open In Bin 以二进制模式打开 - - + + Remove Head Blank 去除行首空白 - - + + Remove End Blank 去除行尾空白 - - + + Remove Head End Blank 去除行首尾空白 - - + + Column Block Editing 列块编辑 - - + + Wrap 自动换行 - - + + Define Language 自定义语言 - - + + UPPERCASE 转成大写 - - + + lowercase 转成小写 - - + + Proper Case 每词转成仅首字母大写 - - + + Proper Case (blend) 每词的首字母转成大写 - - + + Sentence case 每句转成仅首字母大写 - - + + Sentence case (blend) 每句的首字母转成大写 - - + + Invert Case 大小写互换 - - + + Random Case 随机大小写 - - + + Remove Empty Lines 移除空行 - - + + Remove Empty Lines (Containing Blank characters) 移除空行(包括空白字符) - - + + UserDefine 用户自定义 - - + + Column Block Mode 列块模式... - - + + TAB to Space TAB 转空格 - - + + Space to TAB (All) 空格转 TAB (全部) - - + + Space to TAB (Leading) 空格转 TAB (行首) - - + + Duplicate Current Line 复制当前行 - - + + Ctrl+D - - + + Remove Duplicate Lines 删除重复行 - - + + Remove Consecutive Duplicate Lines 删除连续的重复行 - - + + Split Lines 分隔行 - - + + Join Lines 合并行 - - + + Move Up Current Line 上移当前行 - - + + Ctrl+Shift+Up - - + + Move Down Current Line 下移当前行 - - + + Ctrl+Shift+Down - - + + Insert Blank Line Above Current 在当前行上方插入空行 - - + + Ctrl+Alt+Return - - + + Insert Blank Line Below Current 在当前行下方插入空行 - - + + Ctrl+Alt+Shift+Return - - + + Reverse Line Order 反排序行 - - + + Randomize Line Order - - + + Sort Lines Lexicographically Ascending 升序排列文本行 - - + + Sort Lines Lex. Ascending Ignoring Case 升序排列文本行(不分大小写) - - + + Sort Lines As Integers Ascending - - + + Sort Lines As Decimals (Comma) Ascending - - + + Sort Lines As Decimals (Dot) Ascending - - + + Sort Lines Lexicographically Descending 降序排列文本行 - - + + Sort Lines Lex. Descending Ignoring Case 降序排列文本行(不分大小写) - - + + Sort Lines As Integers Descending - - + + Sort Lines As Decimals (Comma) Descending - - + + Sort Lines As Decimals (Dot) Descending - - + + Find In Dir 在目录查找 - - + + Ctrl+Shift+D - - - - + + + + 1 - - + + + Format Xml 格式化 Xml - - + + + Format Json 格式化 Json - - + + Dark 深色 - - + + VB - - + + 2 - - + + 3 - - + + 4 - - + + 5 - - + + loop - - + + Clear History 清除历史打开记录 - - + + + FileListView + 文件列表窗口 + + + + + Show ToolBar + 显示工具栏 + + + + + + Batch Find + 批量查找替换 + + + + + Show Web Addr(Not recommended) + 显示网站(不推荐开启) + + + + Find Next 查找下一个 - - + + + menuDir + 目录对比记录 + + + + + menuReceFile + 文件对比记录 + + + + + Tools(&O) + 工具(&O) + + + + F3 - - + + Find Prev 查找前一个 - - + + F4 - - + + Red - - + + Blue - - - - + + + + Big5 Big5(繁体中文) - - + + 24x24 - - + + 36x36 - - + + 48x48 - - + + AboutNdd About ndd 关于Ndd @@ -1746,90 +1992,90 @@ 信息 - - + + Ln:0 Col:0 行 0 列 0 - - + + Quit 退出 - + Edit with Notepad-- Edit with Notebook CC - + Close Current Document 关闭当前文档 - + Close Non-Current documents 关闭所有非当前文档 - + Close Left All 关闭左边所有文档 - + Close Right All 关闭右边所有文档 - + Current Document Sava as... 当前文件另存为 - + Show File in Explorer... 定位到文件路径 - + Open in New Window 在新窗口中打开 - + Can't Get Admin Auth, Open File %1 failed 获取管理员权限失败,打开文件 %1 失败。修改系统文件请以管理员权限执行ndd程序。 - + Please run in admin auth 请在管理员权限下执行程序 - + Rename Current Document 重命名当前文件 - + Reload With Text Mode 重新以文本模式打开 - + Reload With Hex Mode 重新以二进制模式打开 - + Select Left Cmp File 选择为左边对比文件 - + Select Right Cmp File 选择为右边对比文件 @@ -1838,186 +2084,213 @@ 大文本文件只读模式 - + New File 新建 - + Open File 打开 - - + + Save File 保存 - + Save All File 保存所有 - + Cycle Auto Save 周期自动保存 - + Mark 标记 - + word highlight(F8) 高亮单词(F8) - + clear all highlight(F7) 取消所有高亮(F7) - + Zoom In 放大 - + Zoom Out 缩小 - + Word Wrap 自动换行 - + Show Blank 显示空白字符 - + Indent Guide 缩进参考线 - + Pre Hex Page 上一页/位置 - + Next Hex Page 下一页/位置 - + Goto Hex Page 跳转到文件偏移地址 - + File Compare 文件对比 - + Dir Compare 目录对比 - + Bin Compare 二进制对比 - + transform encoding 转换编码 - + batch rename file 批量重命名 - + + Zoom: %1% + 缩放率: %1% + + + Big5(Traditional Chinese) Big5(繁体中文) - + New File Finished [Text Mode] Zoom %1% 创建新文件成功 缩放率 %1% - + + Use < (Pre) or > (Next) and Goto Buttons to Change Page Num . + 使用工具栏按钮 < (前一页) >(下一页) Go(跳转) 进行翻页。 + + + + File %1 +File Size %2 > %3M, How to Open it ? + 文件 %1 + 文件大小 %2 大于 %3M,请选择打开方式。 + + + File %1 Open Finished [Text Mode] Zoom %2% 文件 %1 打开成功 [文本模式] 缩放率 %2% - - - Current Zoom Value is %1% - + + File List + 文件列表 - + + Save Swap File %1 failed. Write the target file directly ? + 保存交换文件 %1 失败,是否直接保存写入原始文件? + + + + + Current Zoom Value is %1% + 当前缩放率 %1% + + + Ndd Version %1 - + Registered Version 注册过的正版软件!(恭喜) - + Free Trial 免费永久试用版本(捐赠可获取注册码) - + %1 is not a file, skip open it... %1 不是一个文件,跳过打开它...... - - - + + + The ReadOnly document does not allow this operation. 当前只读显示文件不允许该操作! - + Column Edit Mode Tips 列块模式提示 - + "ALT+Mouse Click" or "Alt+Shift+Arrow keys" Switch to mode! 请使用'ALT+鼠标点选' 或 'Alt+Shif+箭头键'切换列块模式。 - + SortingError 排序错误 - + Unable to perform numeric sorting due to line %1. 行 %1 不能进行排序操作! - + Xml format error, please check! Xml 格式化错误,请检查文件格式! - + Json format error, please check! Json 格式化错误,请检查文件格式! @@ -2026,101 +2299,100 @@ 已打开的窗口背景颜色,将在文件重新打开后才会生效! - + GB18030(Simplified Chinese) GB18030(简体中文) - + Language: %1 语法:%1 - + Reload 重加载 - + Yes 保存 - - + + No 放弃修改 - + Cancel 取消 - - + + Restore Last Temp File %1 Failed 恢复临时文件 %1 失败! - + Recover File? 是否恢复文件? - + File %1 abnormally closed last time , Restore it ? 文件 %1 上次异常退出并留下未保存存档,是否恢复文件存档? - + Restore 恢复文件? - + File %1 Open Failed 文件 %1 打开失败! - + File %1 Open Finished [Text Mode] 文件 %1 打开成功 [文本模式] - - + + Current offset is %1 , load Contens Size is %2, File Total Size is %3 当前文件偏移 %1 , 加载内容大小是 %2,文件总大小是 %3 (字节) - + File %1 Open Finished [Hex ReayOnly Mode] 文件 %1 打开成功 [二进制只读模式] - file %1 may be a hex file , try open with text file. - 文件 %1 可能是二进制文件,尝试以文本格式打开。 + 文件 %1 可能是二进制文件,尝试以文本格式打开。 - + Save File %1 failed. You may not have write privileges Please save as a new file! 保存文件 %1 失败! 你可能没有文件写权限,请另存为一个新文件! - + Cycle autosave on ... 周期性自动保存文件已开启... - + Cycle autosave off ... 周期性自动保存文件已关闭... - + The current document has been automatically saved 当前文件周期性自动保存完毕! @@ -2137,17 +2409,17 @@ Do you want to reload it? %1\n\n \n文件已在外部被其它程序修改。\n是否重新加载该文件? - + Ln: %1 Col: %2 行:%1 列:%2 - + Save File? 保存文件? - + if save file %1 ? 是否保存文件 %1 ? @@ -2156,30 +2428,31 @@ Do you want to reload it? 当前文件偏移 %1 , 文件大小是 %2 (字节) - - - - - - - + + + + + + + + Error 错误 - + file %1 not exist. 文件 %1 不存在 - - + + file %1 already open at tab %2 文件 %1 已经在页面 %2 中打开 - - + + Save File %1 failed. Can not write auth, Please save as new file 保存 %1 失败。当前文件没有写权限,请另存为一个新文件 @@ -2188,133 +2461,143 @@ Do you want to reload it? 打开文件 %1 失败 - - - - + + + + Only Text File Can Use it, Current Doc is a Hex File ! 只有文本模式才能使用该功能,当前文件是二进制文件! - + "%1" This file has been modified by another program. Do you want to reload it? %1 该文件已在外部被其它程序修改,是否重新加载? - + Run As Admin Failed to save the file. Please check the file permissions. 以管理员模式保存文件失败!请检查文件的权限。 - + + Plugin Manager + 插件管理 + + + + Plugin + 插件 + + + If display exceptions,Please Install System Font Courier 如果界面字体不满意,还请安装windows系统字体 Courier - + Set/Remove BookMark 设置/取消书签 - + Next BookMark 下一书签 - + Prev BookMark 上一书签 - + ClearAll BookMark 清除所有书签 - + Cut BookMark Lines 剪切书签行 - + Copy BookMark Lines 复制书签行 - + Paste BookMark Lines 粘贴(替换)书签行 - + Delete BookMark Lines 删除书签行 - + Delete UnBookMark Lines 删除未标记行 - + Clip BookMark 反向标记书签 - + Color %1 颜色 %1 - + The currently file %1 is already in text mode 当前文件 %1 已经是文本模式 - + The currently file %1 is already in bin mode 当前文件 %1 已经是二进制模式 - - + + File %1 Open Finished [Text ReadOnly Mode] (Note: display up to 50K bytes ...) 文件 %1 打开成功 [文本只读模式] (乱码:二进制文件强行以文本格式显示,最多显示50K字节的内容,后面忽略...) - - + + file %1 already open at tab %2, please select other file name. 文件 %1 已经存在于页面 %2 中,请选择一个其它名称 - + Rename File As ... 重命名... - + file %1 reanme failed! 文件 %1 重命名失败! - - + + Save File As ... 另存为文件 ... - + Close ? 关闭? - + already has child window open, close all ? 目前还有子窗口处于打开状态,关闭所有窗口吗? - + Find result 查找结果 @@ -2323,49 +2606,50 @@ Do you want to reload it? 文件已关闭 - - + + Find result - %1 hit 查找结果 - %1 命中 - + Convert end of line In progress, please wait ... 行尾转换中,请等待... - + Convert end of line finish. 行尾转换完毕 - + Go to line 跳转到行 - + Line Num: 行号 - + no more pre pos 没有前一个位置了 - + no more next pos 没有后一个位置了 - - + + + The Last Page ! Current offset is %1 , load Contens Size is %2, File Total Size is %3 最后一页!当前文件偏移是 %1 ,加载内容大小是 %2 ,文件总大小是 %3 (字节) - + Only Hex File Can Use it, Current Doc not a Hex File ! 只有二进制文件具备该功能。当前文件不是二进制文件! @@ -2374,31 +2658,31 @@ Do you want to reload it? 最后一页!当前文件偏移是 %1 ,文件大小是 %2 (字节) - + file %1 was not exists ! 文件 %1 不存在! - - + + Error file offset addr , please check ! 错误的文件偏移量地址,请检查! - - + + File Size is %1, addr %2 is exceeds file size 文件大小是 %1,当前地址 %2 超过了文件大小。 - + Current Text Doc Can Not Use it ! Current Text Doc Canp Not Use it ! 当前是常规文本文档,不能使用该功能! - - + + bugfix: https://github.com/cxasm/notepad-- china: https://gitee.com/cxasm/notepad-- bugfix: https://github.com/cxasm/notepad-- @@ -2406,14 +2690,14 @@ china: https://gitee.com/cxasm/notepad-- 国内:https://gitee.com/cxasm/notepad-- - - + + notice 消息 - - + + file path not exist, remove recent record! 文件路径不存在,删除历史记录! @@ -2467,93 +2751,99 @@ china: https://gitee.com/cxasm/notepad-- ColumnEdit - + ColumnEdit 列块编辑 - + Insert Text 插入文本 - - + + Ok 确定 - - + + Close 关闭 - - + + Insert Num 插入数字 - - + + Initial value: 初始值: - - - - + + + + 1 - - + + increment: 增量值: - - + + Repetitions: 重复次数: - - + + prefix string: 前缀字符串: - - + + Format 格式 - - + + Decimal 十进制 - - + + Hex 16进制 - - + + + Capital + + + + + Octal 八进制 - - + + Binary 二进制 @@ -2609,318 +2899,336 @@ china: https://gitee.com/cxasm/notepad-- 时间 - + rule 规则 - + all 全部 - + diff 不同 - + expand 展开 - + fold 收起 - + clear 清空 - + swap 交换 - + reload 重载 - + Status: normal 状态:正常 - - + + error: %1 not a dir ! 错误:%1 不是一个目录! - + now busy, please try later ... 当前忙,稍后再试... - - + + Copy to right 拷贝到右边 - - + + Cover Diffent File To Right 覆盖不同文件到右边 - - + + Cover Diffent File To Right (Traverse subdirectories) 覆盖不同文件到右边(递归子目录) - - + + Copy to left 拷贝到左边 - - + + Cover Diffent File To Left 覆盖不同文件到左边 - - + + Cover Diffent File To Left (Traverse subdirectories) 覆盖不同文件到左边(递归子目录) - + Mark as equal 标记为相等 - + Copy Unique File To Other Side 拷贝独有文件到对方 - + Copy Unique File To Other Side (Traverse subdirectories) 拷贝独有文件到对方(递归子目录) - + Delete This File 删除该文件 - + Delete Only in This Side 删除本侧独有文件 - + Cope Path To Clipboard 拷贝文件路径到剪切板 - + Find File By Name 查找文件 - + %1 not exist, please check! 文件 %1 不存在,请检查! - - - - - - - + + + + + + + Notice 消息 - + del file %1 success! 删除文件 %1 成功! - + del file %1 failed, maybe other place using ! 删除文件 %1 失败,可能其它地方在使用中! - + Do you want to delete this files ? 您确定删除该文件吗? - + right Dirs No Find Prev! 右边目录没有找到前一个! - + right Dirs No Find Next! 右边目录没有找到下一个! - - - + + + Not Find 没有找到 - + left Dirs No Find Next! 左边目录没有找到下一个! - + left Dirs No Find Prev! 左边目录没有找到上一个! - + can not find %1 没有找到相关文件 %1 - + Do you want to overwrite all files (excluding folders) to the other side? 您确定覆盖目录下所有不同文件到对方吗?(不递归子目录) - - + + cover file %1 please waiting 覆盖文件 %1 请等待 - - - - + + + + cover file finish, total cover %1 files 覆盖文件完成,一共覆盖 %1 个文件 - + Do you want to overwrite all files (Traverse subdirs) to the other side? 您确定覆盖目录下所有不同文件到对方吗?(递归覆盖子目录) - + Do you want to copy unique files (excluding folders) to the other side? 您确定拷贝此目录下独有文件到对方?(不递归子目录) - + Do you want to copy unique files (Traverse subdirs) to the other side? 您确定拷贝此目录下独有文件到对方?(递归拷贝子目录) - + Do you want to delete all files (excluding folders) only in this side? 您确定删除目录下的独有文件吗?(不递归子目录) - + delete file finish, total del %1 files 删除文件完成,一共删除 %1 个文件 - - - + + + %1 not exist, skip ... 文件 %1 不存在,跳过... - - - + + + %1 is exist, if replace ? %1 已经存在,是否替换文件? - - - + + + Replace ? 是否替换? - - - + + + copy file %1 failed, please check file auth ! 拷贝文件 %1 失败,请检查文件权限! - - + + current file: %1 current file %1 当前文件:%1 - + + + Yes + + + + + + No + 放弃修改 + + + + + Cancel + 取消 + + + current exec rule mode is quick mode, please wait ... 当前执行的对比模式是快速模式,请等待... - + current exec rule mode is deep slow mode, please wait ... 当前执行的对比模式是深入文本慢速模式,请等待... - + There are still %1 files haven't returned comparison results 还有 %1 个文件正在对比中 - + file is %1 in comparing ! 文件 %1 对比进行中! - + load dir file tree in progress , please wait ... 正在加载文件树目录,请等待... - - + + skip dir %1 跳过目录 %1 - + load %1 dir %2 加载第 %1 个目录 %2 - + skip file ext %1 跳过文件类型 %1 - + skip file prefix %1 跳过文件前缀 %1 @@ -2934,65 +3242,65 @@ china: https://gitee.com/cxasm/notepad-- 文件 [%1] 可能不是文本文件,比较操作危险,强行比较吗?(不建议) - - + + Open Directory 打开目录 - + init dir file tree in progress total %1 file, please wait ... 初始化文件树目录中,一共 %1 文件,请等待... - - - + + + Comparison in progress, please wait ... 对比文件进行中,请等待... - - - - + + + + file [%1] may be not a text file, cmp in hex mode? 文件 %1 可能不是文本格式,是否进行二进制格式对比? - - - - + + + + compare canceled ... 对比被取消 - + compare not finished, user canceled ... 对比没有完成,用户取消 - - + + user canceled finished ... 用户取消完成 - - - + + + compare file finish ... 文件对比完成 - + load dir files, please wait ... 加载目录中,请等待... - + load dir finish, total %1 files 加载目录完成,一共加载 %1 个文件 @@ -3112,8 +3420,8 @@ Left Equal ratio %4 Right Equal ratio %5 - - + + Save File @@ -3121,8 +3429,8 @@ Left Equal ratio %4 Right Equal ratio %5 - - + + left text code 左边编码 @@ -3233,115 +3541,115 @@ Left Equal ratio %4 Right Equal ratio %5 - - + + right text code 右边编码 - - + + white 空白 - - + + rule 规则 - - + + break 打断 - + pull 拉开 - + pull open 拉开对比显示 - - + + strict 严格 - - + + ignore 忽略 - - + + undo 撤销 - + pre 上一个 - + pre (F3) 上一个(F3) - + next 下一个 - + next (F4) 下一个(F4) - + zoomin 放大 - + zoomout 缩小 - + clear 清空 - + clear current compare 清空当前对比 - + swap 交换 - + Can not save file ! - + Save File As ... 另存为文件 ... - + Diff Status @@ -3354,93 +3662,93 @@ Left Equal ratio %4 Right Equal ratio %5 重载(F5) - + Drag file support ... 支持文件拖动... - - - - - - + + + + + + current has %1 differents 当前有 %1 处不同块 - + Current mode can not save file ! 当前模式不能保存文件! - - + + open file %1 failed 打开文件 %1 失败 - - + + save file finished ! 保存文件成功! - - - - + + + + The left document has been modified. 左边文档已经被修改 - - - - + + + + The right document has been modified. 右边文档已经被修改 - - - - + + + + Do you want to save your changes? 是否保存修改? - - + + Save 保存 - - + + Discard 放弃修改 - - + + Cancel 取消 - - + + no more unequal block! 没有更多不等块! - + the first one! 第一个不等块! - - + + the %1 diff, total %2 diff 第 %1 处不同, 一共 %2 不同 @@ -3449,74 +3757,74 @@ Left Equal ratio %4 Right Equal ratio %5 第 %1 处不同,一共 %2 处不同。 - + already the first one! 已经是第一个不等块! - + the last one! 最后一个不等块! - + already the last one! 已经是最后一个不等块! - - - - - + + + + + Error 错误 - + swap left Right windows 交换左右窗口位置 - + refresh 刷新 - + compare again (F5) 重新对比 - + status 差异图 - + show diff views 显示差异界面 - - + + The current comparison has encountered an error.Quit temporarily. 当前对比发生未知错误,暂时退出。 - + has %1 differents 有 %1 处不同 - - + + Comparison in progress, please wait ... 对比文件进行中,请等待... - - + + file [%1] maybe not a text file, forse cmpare?(dangerous, may be core) 文件 [%1] 可能不是文本,强行使用文本对比?(危险操作) @@ -3525,12 +3833,12 @@ Left Equal ratio %4 Right Equal ratio %5 文件 [%1] 不是文本文件,不能进行比较!!! - + no more undo operator! 没有更多撤销! - + now busy, please try later ... 当前忙,稍后再试... @@ -3908,78 +4216,78 @@ Left Equal ratio %4 Right Equal ratio %5 定位到文件目录 - + input file ext() 输入文件后缀 - + ext (Split With :) 后缀(用:号分割开) - + Open Directory 打开目录 - + start scan file text code, please wait... 开始扫描文件编码,请等待... - - + + ignore 忽略 - + please wait, total file %1,cur scan index %2, scan finish %3% 请等待,一共 %1个文件,当前扫描第 %2 个,扫描完成率 %3% - + scan finished, total file %1 扫描完成,一共%1个文件 - + already %1 ignore 已经是 %1编码,忽略 - + total file %1,cur deal index %2,finish %3% 一共 %1 个文件,当前处理第 %2 个,完成率%3% - + total file %1,cur deal index %2,finish 100% 一共 %1 个 文件,当前处理第 %2 个,完成率100% - + convert finished ! 转换完成! - + convert finish 转换完成 - + convert fail 转换失败 - + file %1 convert failed,pleas check... 文件 %1 转换编码失败,请检查... - + please drop a file dir ... 请拖入一个文件夹... @@ -4066,52 +4374,74 @@ Left Equal ratio %4 Right Equal ratio %5 取消 + + FileListView + + + Show File in Explorer + 定位到文件目录 + + + + Close File + 关闭文件 + + + + FileListViewClass + + + + FileListView + 文件列表窗口 + + FileManager - - - + + + Error 错误 - + Open File %1 failed Can not read auth 打开文件 %1 失败。没有读文件的权限。 - + Open File %1 failed 打开文件 %1 失败。 - + File is too big to be opened by Notepad-- 文件太大,不能使用Notepad--打开! - + The file %1 is likely to be binary. Do you want to open it in binary? 文件 %1 可能是二进制格式,你想以二进制(只读)格式打开文件吗? - + Open with Text or Hex? 二进制或文本打开? - + Hex Open 以二进制打开 - + Text Open 以文本打开 - + Cancel 取消 @@ -4302,23 +4632,29 @@ Left Equal ratio %4 Right Equal ratio %5 %1 行已经被复制到剪切板 - + <font style='font-weight:bold;color:#343497'>Search "%1" (%2 hits)</font> <font style='font-weight:bold;color:#343497'>查找 "%1" (%2 命中)</font> - + <font style='font-weight:bold;color:#309730'>%1 (%2 hits)</font> <font style='font-weight:bold;color:#309730'>%1 (%2 命中)</font> - - Line <font style='color:#ff8040'>%1</font> : %2 + + <font style='color:#99cc99'>%1 (%2 hits)</font> + + + + + <font style='color:#ff8040'>Line %1</font> : %2 + Line <font style='color:#ff8040'>%1</font> : %2 行 <font style='color:#ff8040'>%1</font> : %2 - + <font style='font-weight:bold;color:#343497'>Search "%1" (%2 hits in %3 files)</font> <font style='font-weight:bold;color:#343497'>查找 "%1" (%2 命中在 %3 个文件)</font> @@ -4338,367 +4674,375 @@ Left Equal ratio %4 Right Equal ratio %5 FindWin - - + + MainWindow 查找与替换 - - + + find 查找 - - - - - - + + + + + + Find what : 查找目标: - - - - + + + + Backward direction 反向查找 - - - - - - - - + + + + + + + + Match whole word only 全词匹配 - - - - - - - - + + + + + + + + Match case 匹配大小写 - - - - + + + + Wrap around 循环查找 - - - - - - - - + + + + + + + + Search Mode 查找模式 - - - - - - - - + + + + + + + + Regular expression 正则表达式 - - - - - - - - + + + + + + + + Normal 普通 - - - - - - - - + + + + + + + + Extend(\n,\r,\t,\0,\x...) 扩展(\n,\r,\t,\0,\x...) - - + + Find Next(F3) 查找下一个(F3) - - + + F3 - - + + Find Prev(F4) 查找上一个(F4) - - + + F4 - - + + Counter(T) 计数(T) - - + + Ctrl+T - - + + Find Next 查找下一个 - - + + + File Type : + 文件类型: + + + + + Skip Dir Name : + 跳过目录名: + + + + Clear All 清除全部标记 - - + + Find All in Current Document 在当前文件中查找 - - + + Find All in All Opened Documents 查找所有打开文件 - - - - - - - - + + + + + + + + Close 关闭 - - - - + + + + Replace 替换 - - - - + + + + Replace with : 替换为: - - + + Replace All 在当前文件中替换 - - + + Replace All in All Opened Documents 替换所有打开文件 - - + + Replace In File 在目录文件中替换 - - - - + + + + Clear Result 清空结果 - - + + Mark 标记 - - + + Mark What 标记目标: - - + + Mark All 全部标记 - - + + Clear Mark 清除 - - + + Dir Find 在目录查找 - - + + Dest Dir : 目标目录: - - + + Select 选择 - - File Type - 文件类型: + 文件类型: - - + + *.c:*.cpp:*.h - - Skip Dir Name - 跳过目录名 + 跳过目录名 - - + + debug:Debug:.vs:.git:.svn - - + + Options 选项 - - + + Skip child dirs 跳过子目录 - - + + Skip hide file 跳过隐藏文件 - - + + Skip binary file 跳过二进制文件 - - + + Skip Big file exceed 跳过超过大小的文件 - - + + MB - - + + Find All 全部查找 - - - - - - - - - + + + + + + + + + what find is null ! 查找字段为空 - - - - + + + + cant't find text '%1' 找不到字段 '%1' - + no more find text '%1' 没有更多的字段 '%1' @@ -4706,32 +5050,33 @@ Left Equal ratio %4 Right Equal ratio %5 - + The ReadOnly document does not allow this operation. 当前只读显示文件不允许该操作! - - + + find finished, total %1 found! 查找完成,一共 %1 处发现。 - + The mode of the current document does not allow this operation. 当前模式下的文档不允许该操作! - - - + + + + The ReadOnly document does not allow replacement. 当前只读文档不允许执行替换操作! - - + + no more replace text '%1' 没有更多替换文本 '%1' @@ -4752,145 +5097,150 @@ Left Equal ratio %4 Right Equal ratio %5 计数 %1 次匹配 '%2' - - + + total %1 keyword, please wait ... + + + + + The mode of the current document does not allow replacement. 当前模式的文档不允许执行替换操作! - - + + Replace All current Doc 在所有打开文件中替换 - - + + Are you sure replace all occurrences in current documents? 是否确认在当前打开的文档中替换? - - + + replace finished, total %1 replaced! 替换完成,一共 %1 处替换! - + Replace All Open Doc 替换所有打开的文档 - + Are you sure replace all occurrences in all open documents? 是否确认在所有打开的文档中替换? - + Replace in Opened Files: %1 occurrences were replaced. 在打开的文档中替换:%1 处已经被替换。 - - + + what mark is null ! 标记字段为空! - + cant't mark text '%1' 不能标记文本 ‘%1’ - + mark finished, total %1 found! 标记完成,一共 %1 处发现! - + The mode of the current document does not allow mark. 当前模式的文档不允许执行标记操作! - + Open Directory 打开目录 - + load dir file in progress , please wait ... 加载目录文件中,请等待... - - + + skip dir %1 跳过目录 %1 - + found %1 dir %2 发现 %1 个目录 %2 - + ext type skip file %1 跳过类型文件 %1 - + found in dir canceled ... 查找取消... - + Continue Find ? 是否继续查找? - + The search results have been greater than %1 times in %2 files, and more may be slow. Continue to search? 查找结果已经有 %1 处在 %2 个文件中,结果太多会比较慢,是否继续查找? - + Yes 继续查找 - + Abort 终止查找 - - + + please select find dest dir ! 请选择目标文件夹! - + dest dir %1 not exist ! 目标文件夹 %1 不存在! - + find finished, total %1 found in %2 file! 查找完成,一共发现 %1 处在 %2 个文件中! - + Replace All Dirs 目录全部替换 - + Are you sure replace all "%1" to "%2" occurrences in selected dirs ? 您确定替换目录文件中所有 "%1" 为 "%2" 吗? - + replace finished, total %1 replace in %2 file! 替换完成,一共替换 %1 处在 %2 个文件中! @@ -5285,15 +5635,15 @@ Select a shorter range for comparison. 请安装至少一种系统字体[[Courier/SimSun/Times New Roman]。软件界面字体显示可能不满意。 - - - + + + The new software has been released, please update it timely! 软件新版本已经发布,请及时更新! - - + + Software status is normal. 软件状态正常 @@ -5310,7 +5660,7 @@ Select a shorter range for comparison. 消息 - + Please contact us. QQ Group:959439826 请加入我们QQ群:959439826 @@ -5379,6 +5729,57 @@ Select a shorter range for comparison. 文本和字体 + + PluginMgrClass + + + + PluginMgr + 插件管理 + + + + + Name + 文件名 + + + + + Version + 版本 + + + + + Auther + 作者 + + + + + Comment + 说明 + + + + + Path + 路径 + + + + + Plugin Dir + 插件目录 + + + + + Close + 关闭 + + ProgressWin @@ -5417,27 +5818,27 @@ Select a shorter range for comparison. QObject - + Text Mode 文本模式 - + Hex ReadOnly Mode 二进制只读模式 - + Bit Text ReadOnly Mode 大文本只读模式 - + Text ReadOnly Mode 文本只读模式 - + File Mode 文件模式 @@ -5518,10 +5919,117 @@ Select a shorter range for comparison. 定位到文件目录 + + QsciLexerGlobal + + Global override + 全局样式覆盖所有语言 + + + Default + 默认 + + + Indent guideline style + 缩进参考线风格 + + + Brace highlight style + 括弧高亮风格 + + + Bad brace colour + + + + Current line background colour + 当前行背景色 + + + Select text colour + 选中文本颜色 + + + Caret colour + 光标颜色 + + + Edge colour + + + + Line number margin + 行号风格 + + + Bookmark margin + 书签风格 + + + Fold + 折叠符号风格 + + + Fold active + 折叠激活风格(目前无效) + + + Fold margin + 折叠样式 + + + White space symbol + 空白字符样式 + + + Smart HighLighting + 智能高亮 + + + Find Mark Style + 查找结果样式 + + + Mark Style 1 + 标记样式1 + + + Mark Style 2 + 标记样式2 + + + Mark Style 3 + 标记样式3 + + + Mark Style 4 + 标记样式4 + + + Mark Style 5 + 标记样式5 + + + Incremental highlight + + + + Tags match highlight + + + + Tags attribute + + + + URL hovered + 网址鼠标悬浮样式 + + QtLangSet - + Save Change 保存修改 @@ -5530,253 +6038,401 @@ Select a shorter range for comparison. 当前语言的格式风格已经被修改,是否保存? - + + AllGlobal 全局格式统一设置 - + + Current themes : %1, language : %2 + 当前主题:%1,当前语言:%2 + + + %1 style configuration has been modified. Do you want to save it? %1 类型的显示风格已经被修改,是否保存? - + Read %1 language user define format error. 读取 %1 语言用户自定义格式失败! - + + Save Finished ! + 保存成功! + + + + Not change, no need save ! + 没有改变,无需保存! + + + Style Foreground Color 风格背景色 风格前景色 - + Style Background Color 风格背景色 - + Reset Style 重置风格 - + Are you sure to reset language %1 sytle 您确定重置语言 %1 的风格吗? - + Reset All Style 重置所有风格 - + Are you sure to reset All language sytle 您确定重置所有语言风格吗? + + + themes changing, please waiting ... + 主题切换中,请等待 ... + + + + themes changed finished ... + 主题切换完成 ... + QtLangSetClass - + QtLangSet - 编程语言风格设置 + 编程语言样式 - - + + + Select Main: + 选择主题: + + + + + Default(stylers.xml) + 默认主题 + + + + + Bespin + + + + + + Black board + + + + + + Blue Light + + + + + + Choco + + + + + + DansLeRuSH-Dark + + + + + + Deep Black + + + + + + Lavender + + + + + + HotFudgeSundae + + + + + + Misty Rose + + + + + + Mono Industrial + + + + + + Monokai + + + + + + Obsidian + + + + + + Plastic Code Wrap + + + + + + Ruby Blue + + + + + + Twilight + + + + + + Vibrant Ink + + + + + + Yellow Rice + + + + + Language 语言 - - + + User Define Language 自定义语言 - - + + Style - 语法风格项 + 样式 - - + + Color 颜色 - - + + Foreground: 前景色 - - + + + + TextLabel - - - - + + + + Select 选择 - - - - All Style - 修改所有风格 + 修改所有风格 - - + + background: 背景色 - - + + Same As Theme 与主题保存一致 - - + + Font 字体 - - + + Font Size: 字体大小 - - + + Bold 粗体 - - + + Italic 斜体 - - + + Underline 下划线 - - + + Name: 名称: - - + + + Use Global Color + 全局颜色 + + + + Keyword And Mother 关键词和母版 - - + + Mother Language: 母版语言: - - + + None - - + + Cpp - - + + Ext File Type: 关联文件后缀名: - - Global Style Set - 全局风格设置 + 全局风格设置 - - + + Use Global Foreground Color 使用全局前景色 - - + + Use Global Background Color 使用全局背景色 - - + + + Global Style Font + 全局样式字体 + + + + Use Global Font 使用全局字体 - - + + Use Global FontSize 使用全局字体大小 - - + + Use Global Bold Font 使用全局粗体样式 - - + + Use Global Italic Font 使用全局斜体样式 - - + + Use Global Underline Font 使用全局下划线样式 - - + + reset 重置 - - + + Save 保存 - - + + Close 关闭 @@ -6060,30 +6716,49 @@ Select a shorter range for comparison. ScintillaEditView - + Show File in Explorer 定位到文件目录 - + + mark with color 使用颜色标记 - + + Color %1 颜色 %1 - + + Clear Select 清除选择标记 - + + Clear All 清除全部标记 + + + Add/Del line comment + 添加/删除当行注释 + + + + Add Block comment + 区块注释 + + + + Del Block comment + 清除区块注释 + StatusWidget diff --git a/src/scintillaeditview.cpp b/src/scintillaeditview.cpp index 43942c4..60181dd 100755 --- a/src/scintillaeditview.cpp +++ b/src/scintillaeditview.cpp @@ -59,6 +59,7 @@ #include #include #include +#include #include @@ -82,6 +83,9 @@ const int ScintillaEditView::_SC_MARGE_LINENUMBER = 0; const int ScintillaEditView::_SC_MARGE_SYBOLE = 1; const int ScintillaEditView::_SC_MARGE_FOLDER = 2; +//大文本是分块显示,务必要把真实的偏移行号给显示出来 +const int SC_BIGTEXT_LINES = 0; + const int MAX_PRE_NEXT_TIMES = 30; #ifdef Q_OS_WIN @@ -185,8 +189,8 @@ LanguageName ScintillaEditView::langNames[L_EXTERNAL + 1] = { }; #endif -ScintillaEditView::ScintillaEditView(QWidget *parent) - : QsciScintilla(parent), m_NoteWin(nullptr), m_preFirstLineNum(0), m_curPos(0), m_hasHighlight(false), m_bookmarkPng(nullptr), m_styleColorMenu(nullptr) +ScintillaEditView::ScintillaEditView(QWidget *parent,bool isBigText) + : QsciScintilla(parent), m_NoteWin(nullptr), m_preFirstLineNum(0), m_curPos(0), m_hasHighlight(false), m_bookmarkPng(nullptr), m_styleColorMenu(nullptr), m_isBigText(isBigText) { init(); } @@ -201,6 +205,11 @@ ScintillaEditView::~ScintillaEditView() } } +void ScintillaEditView::setBigTextMode(bool isBigText) +{ + m_isBigText = isBigText; +} + void ScintillaEditView::setLexer(QsciLexer * lexer) { QsciScintilla::setLexer(lexer); @@ -208,10 +217,12 @@ void ScintillaEditView::setLexer(QsciLexer * lexer) if (lexer != nullptr && lexer->lexerId() == L_TXT) { showMargin(_SC_MARGE_FOLDER,false); + updateThemes(); } else if(lexer != nullptr && lexer->lexerId() != L_TXT) { showMargin(_SC_MARGE_FOLDER, true); + updateThemes(); } } @@ -240,7 +251,11 @@ void ScintillaEditView::updateLineNumbersMargin(bool forcedToHide) { //根据现有滚动条来决定是否更新屏幕线宽长度。每滚动200个单位必须调整line宽 void ScintillaEditView::autoAdjustLineWidth(int xScrollValue) { - + //如果是大文本模式,是没有行号的,直接返回 + if (m_isBigText) + { + return; + } if (std::abs(xScrollValue - m_preFirstLineNum) > 200) { m_preFirstLineNum = xScrollValue; @@ -251,19 +266,21 @@ void ScintillaEditView::autoAdjustLineWidth(int xScrollValue) void ScintillaEditView::updateLineNumberWidth(int lineNumberMarginDynamicWidth) { + if (!m_isBigText) + { auto linesVisible = execute(SCI_LINESONSCREEN); if (linesVisible) { int nbDigits = 0; - if(lineNumberMarginDynamicWidth != 0) + if (lineNumberMarginDynamicWidth != 0) { int firstVisibleLineVis = execute(SCI_GETFIRSTVISIBLELINE); int lastVisibleLineVis = linesVisible + firstVisibleLineVis + 1; int lastVisibleLineDoc = execute(SCI_DOCLINEFROMVISIBLE, (long)lastVisibleLineVis); nbDigits = nbDigitsFromNbLines(lastVisibleLineDoc); - nbDigits = nbDigits < 3 ? 3 : nbDigits; + nbDigits = nbDigits < 4 ? 4 : nbDigits; } else { @@ -271,9 +288,18 @@ void ScintillaEditView::updateLineNumberWidth(int lineNumberMarginDynamicWidth) nbDigits = nbDigitsFromNbLines(nbLines); nbDigits = nbDigits < 4 ? 4 : nbDigits; } - + auto pixelWidth = 6 + nbDigits * execute(SCI_TEXTWIDTH, STYLE_LINENUMBER, reinterpret_cast("8")); execute(SCI_SETMARGINWIDTHN, _SC_MARGE_LINENUMBER, pixelWidth); + + + } + } + else + { + int nbDigits = 9; + int pixelWidth = 6 + nbDigits * execute(SCI_TEXTWIDTH, STYLE_LINENUMBER, reinterpret_cast("8")); + execute(SCI_SETMARGINWIDTHN, SC_BIGTEXT_LINES, pixelWidth); } } @@ -312,7 +338,7 @@ sptr_t ScintillaEditView::execute(quint32 Msg, uptr_t wParam, sptr_t lParam) con //status : true 表示存在, false 表示不存在 //tag,只有在用户自定义语法是,才需要给出。内部自带的语法不需要给出 //isOrigin:是否原生lexer,即不读取用户修改过的配置风格 -QsciLexer* ScintillaEditView::createLexer(int lexerId, QString tag, bool isOrigin) +QsciLexer* ScintillaEditView::createLexer(int lexerId, QString tag, bool isOrigin, int styleId) { QsciLexer* ret = nullptr; @@ -578,7 +604,12 @@ QsciLexer* ScintillaEditView::createLexer(int lexerId, QString tag, bool isOrigi if (!isOrigin) { - QtLangSet::readLangSettings(ret, ret->lexerTag()); + QtLangSet::readLangSettings(ret, ret->lexerTag(), styleId); + } + else + { + //如果是读取原生风格,则只有默认主题具备,其余主题要从模板中加载 + QtLangSet::readLangOriginSettings(ret, ret->lexerTag(), styleId); } } return ret; @@ -604,22 +635,23 @@ QList& ScintillaEditView::getCurMarkRecord() return m_curMarkList; } -//调整颜色 -void ScintillaEditView::adjuctSkinStyle() -{ - if (StyleSet::m_curStyleId != BLACK_SE) - { - setMarginsForegroundColor(QColor(0x80, 0x80, 0x80)); //默认0x80, 0x80, 0x80 - } - else - { - setMarginsForegroundColor(QColor(0xde, 0xde, 0xde)); //默认0x80, 0x80, 0x80 - } - setMarginsBackgroundColor(StyleSet::marginsBackgroundColor); - setMarginBackgroundColor(_SC_MARGE_SYBOLE, StyleSet::bookmarkBkColor); - setFoldMarginColors(StyleSet::marginsBackgroundColor, StyleSet::marginsBackgroundColor); - setStyleOptions(); -} +////调整颜色 +//void ScintillaEditView::adjuctSkinStyle() +//{ +// if (StyleSet::m_curStyleId != BLACK_SE) +// { +// setMarginsForegroundColor(QColor(0x80, 0x80, 0x80)); //默认0x80, 0x80, 0x80 +// } +// else +// { +// setMarginsForegroundColor(QColor(0xde, 0xde, 0xde)); //默认0x80, 0x80, 0x80 +// } +// setMarginsBackgroundColor(StyleSet::marginsBackgroundColor); +// +// setMarginBackgroundColor(_SC_MARGE_SYBOLE, StyleSet::bookmarkBkColor); +// setFoldMarginColors(StyleSet::marginsBackgroundColor, StyleSet::marginsBackgroundColor); +// setStyleOptions(); +//} void ScintillaEditView::setIndentGuide(bool willBeShowed) { @@ -636,7 +668,6 @@ void ScintillaEditView::setIndentGuide(bool willBeShowed) void ScintillaEditView::init() { - m_pScintillaFunc = (SCINTILLA_FUNC)this->SendScintillaPtrResult(SCI_GETDIRECTFUNCTION); m_pScintillaPtr = (SCINTILLA_PTR)this->SendScintillaPtrResult(SCI_GETDIRECTPOINTER); @@ -651,52 +682,44 @@ void ScintillaEditView::init() throw std::runtime_error("ScintillaEditView::init : SCI_GETDIRECTPOINTER message failed"); } + if (m_isBigText) + { + this->setMarginType(SC_BIGTEXT_LINES, TextMargin); + } + else + { //开启行号marge setMarginLineNumbers(_SC_MARGE_LINENUMBER, true); - - //QColor foldfgColor(StyleSet::foldfgColor); - //QColor foldbgColor(StyleSet::foldbgColor);//默认0xff,0xff,0xff - - + showMargin(_SC_MARGE_LINENUMBER, true); //通过fold发现,尽量使用qscint的功能,因为他做了大量封装和简化 setFolding(BoxedTreeFoldStyle, _SC_MARGE_FOLDER); - //setFoldMarginColors(foldfgColor, foldbgColor);合入adjuctSkinStyle - - //当前fold高亮。QT下面有bug暂时不开启 - //execute(SCI_MARKERENABLEHIGHLIGHT, true); - //setMarginsBackgroundColor(StyleSet::marginsBackgroundColor); //0xea, 0xf7, 0xff //默认0xf0f0f0 - //execute(SCI_MARKERSETBACK, _SC_MARGE_FOLDER, 0x808080); - //execute(SCI_MARKERSETBACKSELECTED, _SC_MARGE_FOLDER, 0xff0000); - - showMargin(_SC_MARGE_LINENUMBER, true); + } //行号、符号、折叠。中间符号留一个很小的间隔。用于圆形的标记符号 showMargin(_SC_MARGE_SYBOLE, true); - setMarginType(_SC_MARGE_SYBOLE, QsciScintilla::SymbolMarginColor); - //execute(SCI_MARKERSETALPHA, _SC_MARGE_SYBOLE, 200); m_bookmarkPng = new QPixmap(QString(":/Resources/img/bookmark.png")); markerDefine(*m_bookmarkPng, _SC_MARGE_SYBOLE); setMarginSensitivity(_SC_MARGE_SYBOLE, true); connect(this, &QsciScintilla::marginClicked, this, &ScintillaEditView::slot_bookMarkClicked); - //setMarginBackgroundColor(_SC_MARGE_SYBOLE, StyleSet::marginsBackgroundColor); - adjuctSkinStyle(); + //adjuctSkinStyle(); //开始括号匹配,比如html的<>,开启前后这类字段的匹配 setBraceMatching(SloppyBraceMatch); - if (StyleSet::m_curStyleId != BLACK_SE) - { - setMatchedBraceForegroundColor(QColor(191, 141, 255)); - setMatchedBraceBackgroundColor(QColor(222, 222, 222)); - } - else - { - setMatchedBraceForegroundColor(QColor(246, 81, 246)); - setMatchedBraceBackgroundColor(QColor(18, 90, 36)); - } + + //if (StyleSet::m_curStyleId != BLACK_SE) + //{ + // setMatchedBraceForegroundColor(QColor(191, 141, 255)); + // setMatchedBraceBackgroundColor(QColor(222, 222, 222)); + //} + //else + //{ + // setMatchedBraceForegroundColor(QColor(246, 81, 246)); + // setMatchedBraceBackgroundColor(QColor(18, 90, 36)); + //} //自动补全效果不好,不开启20211017 //setAutoCompletionSource(QsciScintilla::AcsAPIs); //设置源,自动补全所有地方出现的 @@ -709,88 +732,89 @@ void ScintillaEditView::init() setMarginsFont(font); execute(SCI_SETTABWIDTH, ScintillaEditView::s_tabLens); - //setMarginsBackgroundColor(QColor(0xff, 0xff, 0x80)); - //setPaper(QColor(0xfc, 0xfc, 0xfc));//这个无效 //使用空格替换tab - //execute(SCI_SETUSETABS, !ScintillaEditView::s_noUseTab); - setIndentationsUseTabs(!ScintillaEditView::s_noUseTab); //这个无比要设置false,否则双击后高亮单词,拷贝时会拷贝多个选择。 execute(SCI_SETMULTIPLESELECTION, true); execute(SCI_SETADDITIONALSELECTIONTYPING, true); - //execute(SCI_SETADDITIONALSELALPHA, 100); execute(SCI_SETMULTIPASTE, SC_MULTIPASTE_EACH); execute(SCI_SETADDITIONALCARETSVISIBLE, true); execute(SCI_SETVIRTUALSPACEOPTIONS, SCVS_RECTANGULARSELECTION); - //execute(SCI_SETADDITIONALSELFORE, 0); - //execute(SCI_SETADDITIONALSELBACK, 0x98ff98); - execute(SCI_SETSELFORE, true, 0x0); - //execute(SCI_SETSELBACK, true, 0x9ACC9A); - execute(SCI_SETSELBACK, true, 0x9bff9b); //0x00ffff原来的黄色 + //execute(SCI_SETSELFORE, true, 0x0); + //execute(SCI_SETSELBACK, true, 0x9bff9b); //0x00ffff原来的黄色 //设置查找到Mark的风格。定义其前景颜色和形状 execute(SCI_INDICSETSTYLE, SCE_UNIVERSAL_FOUND_STYLE_EXT5, INDIC_ROUNDBOX); execute(SCI_INDICSETALPHA, SCE_UNIVERSAL_FOUND_STYLE_EXT5, 130); execute(SCI_INDICSETUNDER, SCE_UNIVERSAL_FOUND_STYLE_EXT5, false); - execute(SCI_INDICSETFORE, SCE_UNIVERSAL_FOUND_STYLE_EXT5, 0x00ffff); + //execute(SCI_INDICSETFORE, SCE_UNIVERSAL_FOUND_STYLE_EXT5, 0x00ffff); //设置查找到Mark的风格。定义其前景颜色和形状 execute(SCI_INDICSETSTYLE, SCE_UNIVERSAL_FOUND_STYLE_EXT4, INDIC_ROUNDBOX); execute(SCI_INDICSETALPHA, SCE_UNIVERSAL_FOUND_STYLE_EXT4, 130); execute(SCI_INDICSETUNDER, SCE_UNIVERSAL_FOUND_STYLE_EXT4, false); - execute(SCI_INDICSETFORE, SCE_UNIVERSAL_FOUND_STYLE_EXT4, 0xffff00); + //execute(SCI_INDICSETFORE, SCE_UNIVERSAL_FOUND_STYLE_EXT4, 0xffff00); //设置查找到Mark的风格。定义其前景颜色和形状 execute(SCI_INDICSETSTYLE, SCE_UNIVERSAL_FOUND_STYLE_EXT3, INDIC_ROUNDBOX); execute(SCI_INDICSETALPHA, SCE_UNIVERSAL_FOUND_STYLE_EXT3, 130); execute(SCI_INDICSETUNDER, SCE_UNIVERSAL_FOUND_STYLE_EXT3, false); - execute(SCI_INDICSETFORE, SCE_UNIVERSAL_FOUND_STYLE_EXT3, 0x0080ff); + //execute(SCI_INDICSETFORE, SCE_UNIVERSAL_FOUND_STYLE_EXT3, 0x0080ff); //设置查找到Mark的风格。定义其前景颜色和形状 execute(SCI_INDICSETSTYLE, SCE_UNIVERSAL_FOUND_STYLE_EXT2, INDIC_ROUNDBOX); execute(SCI_INDICSETALPHA, SCE_UNIVERSAL_FOUND_STYLE_EXT2, 130); execute(SCI_INDICSETUNDER, SCE_UNIVERSAL_FOUND_STYLE_EXT2, false); - execute(SCI_INDICSETFORE, SCE_UNIVERSAL_FOUND_STYLE_EXT2, 0xff0080); + //execute(SCI_INDICSETFORE, SCE_UNIVERSAL_FOUND_STYLE_EXT2, 0xff0080); //设置查找到Mark的风格。定义其前景颜色和形状 execute(SCI_INDICSETSTYLE, SCE_UNIVERSAL_FOUND_STYLE_EXT1, INDIC_ROUNDBOX); execute(SCI_INDICSETALPHA, SCE_UNIVERSAL_FOUND_STYLE_EXT1, 130); execute(SCI_INDICSETUNDER, SCE_UNIVERSAL_FOUND_STYLE_EXT1, false); - execute(SCI_INDICSETFORE, SCE_UNIVERSAL_FOUND_STYLE_EXT1, 0xff8000); + //execute(SCI_INDICSETFORE, SCE_UNIVERSAL_FOUND_STYLE_EXT1, 0xff8000); //下面这两个是HTML文件的tag高亮的表示。 execute(SCI_INDICSETSTYLE, SCE_UNIVERSAL_TAGMATCH, INDIC_STRAIGHTBOX); execute(SCI_INDICSETALPHA, SCE_UNIVERSAL_TAGMATCH, 100); execute(SCI_INDICSETUNDER, SCE_UNIVERSAL_TAGMATCH, false); - execute(SCI_INDICSETFORE, SCE_UNIVERSAL_TAGMATCH, 0xff0080); + //execute(SCI_INDICSETFORE, SCE_UNIVERSAL_TAGMATCH, 0xff0080); execute(SCI_INDICSETSTYLE, SCE_UNIVERSAL_TAGATTR, INDIC_STRAIGHTBOX); execute(SCI_INDICSETALPHA, SCE_UNIVERSAL_TAGATTR, 100); execute(SCI_INDICSETUNDER, SCE_UNIVERSAL_TAGATTR, false); - execute(SCI_INDICSETFORE, SCE_UNIVERSAL_TAGATTR, 0x00ffff); + //execute(SCI_INDICSETFORE, SCE_UNIVERSAL_TAGATTR, 0x00ffff); //双击后同样的字段进行高亮 execute(SCI_INDICSETSTYLE, SCE_UNIVERSAL_FOUND_STYLE_SMART, INDIC_ROUNDBOX); execute(SCI_INDICSETALPHA, SCE_UNIVERSAL_FOUND_STYLE_SMART, 100); execute(SCI_INDICSETUNDER, SCE_UNIVERSAL_FOUND_STYLE_SMART, false); - execute(SCI_INDICSETFORE, SCE_UNIVERSAL_FOUND_STYLE_SMART, 0x00ff00); + //execute(SCI_INDICSETFORE, SCE_UNIVERSAL_FOUND_STYLE_SMART, 0x00ff00); + + //设置空白字符的默认前景色 + //execute(SCI_SETWHITESPACEFORE, true, 0x6ab5ff); + execute(SCI_SETWHITESPACESIZE,3); setCaretLineVisible(true); - if (StyleSet::m_curStyleId != BLACK_SE) - { - setCaretLineBackgroundColor(QColor(0xe8e8ff)); - } - else - { - setCaretLineBackgroundColor(QColor(0x333333)); - } + //execute(SCI_INDICSETHOVERFORE, URL_INDIC, 0x80ffff); + + //if (StyleSet::m_curStyleId != BLACK_SE) + //{ + // setCaretLineBackgroundColor(QColor(0xe8e8ff)); + //} + //else + //{ + // setCaretLineBackgroundColor(QColor(0x333333)); + //} + + //统一设置全局前景、背景、字体大小三个要素 + updateThemes(); //记住position变化。不能使用cursorPositionChanged,因为他的列考虑uft8字符,中文一个也算1个,每次列不一定相等。 //要使用自定义的cursorPosChange,跟踪的是SCI_GETCURRENTPOS 的值。换行才会触发这个cursorPosChange。自定义的信号 @@ -800,8 +824,7 @@ void ScintillaEditView::init() execute(SCI_SETSCROLLWIDTH, 1); - //20220226发现高亮全选如果范围过大,会导致卡死。借鉴notepad的只高亮可视化区域。但是滚动时也必须生效 - connect(this->verticalScrollBar(), &QScrollBar::valueChanged, this, &ScintillaEditView::slot_scrollXValueChange); + connect(this->verticalScrollBar(), &QScrollBar::valueChanged, this, &ScintillaEditView::slot_scrollYValueChange); connect(this, &ScintillaEditView::delayWork, this,&ScintillaEditView::slot_delayWork, Qt::QueuedConnection); //设置换行符号的格式 @@ -813,10 +836,65 @@ void ScintillaEditView::init() execute(SCI_SETEOLMODE, SC_EOL_LF); #endif + //开启新行自动缩进 + setAutoIndent(true); + //开启后可以保证长行在滚动条下完整显示 execute(SCI_SETSCROLLWIDTHTRACKING, true); } + +//大文本不能显示行号,其实显示的是每一行的地址。 +//因为要跳转,所以没法实时计算当前位置所在的行号 +void ScintillaEditView::showBigTextLineAddr(qint64 fileOffset) +{ + int nbDigits = 0; + + if (fileOffset < 0xffffffff) + { + nbDigits = 9; + } + else + { + nbDigits = 13; + } + char* lineString = new char[17]; + memset(lineString, 0, 17); + + auto pixelWidth = 6 + nbDigits * execute(SCI_TEXTWIDTH, STYLE_LINENUMBER, reinterpret_cast("8")); + this->execute(SCI_SETMARGINWIDTHN, SC_BIGTEXT_LINES, pixelWidth); + + int lineNums = this->lines(); + int lineLength = 0; + + qint64 curLineAddr = fileOffset; + + int style = STYLE_LINENUMBER; + + for (int i = 0; i < lineNums; ++i) + { + memset(lineString, 0, 17); + + lineLength = this->lineLength(i); + + if (fileOffset < 0xffffffff) + { + sprintf(lineString, "%08llX ", fileOffset); + } + else + { + sprintf(lineString, "%012llX ", fileOffset); + } + + QString num(lineString); + + fileOffset += lineLength; + this->setMarginText(i, num, style); + } + + delete[]lineString; +} + void ScintillaEditView::bookmarkNext(bool forwardScan) { size_t lineno = this->getCurrentLineNumber(); @@ -981,13 +1059,50 @@ void ScintillaEditView::pasteToMarkedLines() this->execute(SCI_ENDUNDOACTION); } -//X方向滚动条值变化后的槽函数。一旦滚动则会出发这里,发送消息给中介,让中介去同步另外一方 -void ScintillaEditView::slot_scrollXValueChange(int value) +//Y方向滚动条值变化后的槽函数 +void ScintillaEditView::slot_scrollYValueChange(int value) { + //使用滚动条翻页的效果并不好。暂时不放开 + /*bool changePage = false; + + qDebug() << value << verticalScrollBar()->maximum() << verticalScrollBar()->minimum(); + + if (value >= this->verticalScrollBar()->maximum()) + { + if (m_NoteWin != nullptr) + { + changePage = m_NoteWin->nextPage(this); + } + } + else if (value == this->verticalScrollBar()->minimum()) + { + if (m_NoteWin != nullptr) + { + changePage = m_NoteWin->prePage(this); + } + }*/ + + if (value >= this->verticalScrollBar()->maximum()) + { + if (m_NoteWin != nullptr) + { + m_NoteWin->showChangePageTips(this); + } + } + else if (value == this->verticalScrollBar()->minimum()) + { + if (m_NoteWin != nullptr) + { + m_NoteWin->showChangePageTips(this); + } + } + slot_delayWork(); autoAdjustLineWidth(value); + } + void ScintillaEditView::deleteMarkedLines(bool isMarked) { std::lock_guard lock(mark_mutex); @@ -1219,6 +1334,72 @@ void ScintillaEditView::slot_markColorGroup(QAction *action) } } +//修改标记样式的颜色 +void ScintillaEditView::changeStyleColor(int sytleId) +{ + if (m_styleColorMenu == nullptr) + { + initStyleColorMenu(); + } + if( sytleId < 5) + { + QPixmap colorBar(36, 36); + colorBar.fill((&StyleSet::s_global_style->mark_style_1)[sytleId].bgColor); + m_styleMarkActList.at(sytleId)->setIcon(colorBar); + + if (m_NoteWin != nullptr) + { + m_NoteWin->changeMarkColor(sytleId); + } + } +} + +void ScintillaEditView::initStyleColorMenu() +{ + if (m_styleColorMenu == nullptr) + { + m_styleColorMenu = new QMenu(tr("mark with color"), this); + QPixmap colorBar(36, 36); + + QActionGroup* markColorGroup = new QActionGroup(this); + connect(markColorGroup, &QActionGroup::triggered, this, &ScintillaEditView::slot_markColorGroup, Qt::QueuedConnection); + + int index = 1; + auto initColorBar = [this, markColorGroup, &index](QPixmap& colorBar)->QAction* { + QAction* action = new QAction(m_styleColorMenu); + action->setIcon(colorBar); + action->setCheckable(true); + action->setText(tr("Color %1").arg(index)); + action->setData(index + SCE_UNIVERSAL_FOUND_STYLE_EXT5 - 1); + ++index; + m_styleColorMenu->addAction(action); + markColorGroup->addAction(action); + return action; + }; + + colorBar.fill(StyleSet::s_global_style->mark_style_1.bgColor); + m_styleMarkActList.append(initColorBar(colorBar)); + + colorBar.fill(StyleSet::s_global_style->mark_style_2.bgColor); + m_styleMarkActList.append(initColorBar(colorBar)); + + colorBar.fill(StyleSet::s_global_style->mark_style_3.bgColor); + m_styleMarkActList.append(initColorBar(colorBar)); + + colorBar.fill(StyleSet::s_global_style->mark_style_4.bgColor); + m_styleMarkActList.append(initColorBar(colorBar)); + + colorBar.fill(StyleSet::s_global_style->mark_style_5.bgColor); + m_styleMarkActList.append(initColorBar(colorBar)); + + + m_styleColorMenu->addSeparator(); + + m_styleColorMenu->addAction(tr("Clear Select"), m_NoteWin, &CCNotePad::slot_clearWordHighlight); + m_styleColorMenu->addAction(tr("Clear All"), m_NoteWin, &CCNotePad::slot_clearMark); + } +} + void ScintillaEditView::contextUserDefineMenuEvent(QMenu* menu) { //QAction* action; @@ -1235,7 +1416,7 @@ void ScintillaEditView::contextUserDefineMenuEvent(QMenu* menu) connect(markColorGroup, &QActionGroup::triggered, this, &ScintillaEditView::slot_markColorGroup, Qt::QueuedConnection); int index = 1; - auto initColorBar = [this, markColorGroup, &index](QPixmap& colorBar) { + auto initColorBar = [this, markColorGroup, &index](QPixmap& colorBar)->QAction* { QAction* action = new QAction(m_styleColorMenu); action->setIcon(colorBar); action->setCheckable(true); @@ -1244,22 +1425,23 @@ void ScintillaEditView::contextUserDefineMenuEvent(QMenu* menu) ++index; m_styleColorMenu->addAction(action); markColorGroup->addAction(action); + return action; }; - colorBar.fill(QColor(0xffff00)); - initColorBar(colorBar); + colorBar.fill(StyleSet::s_global_style->mark_style_1.fgColor); + m_styleMarkActList.append(initColorBar(colorBar)); - colorBar.fill(QColor(0x00ffff)); - initColorBar(colorBar); + colorBar.fill(StyleSet::s_global_style->mark_style_2.fgColor); + m_styleMarkActList.append(initColorBar(colorBar)); - colorBar.fill(QColor(0xff8000)); - initColorBar(colorBar); + colorBar.fill(StyleSet::s_global_style->mark_style_3.fgColor); + m_styleMarkActList.append(initColorBar(colorBar)); - colorBar.fill(QColor(0x8000ff)); - initColorBar(colorBar); + colorBar.fill(StyleSet::s_global_style->mark_style_4.fgColor); + m_styleMarkActList.append(initColorBar(colorBar)); - colorBar.fill(QColor(0x0080ff)); - initColorBar(colorBar); + colorBar.fill(StyleSet::s_global_style->mark_style_5.fgColor); + m_styleMarkActList.append(initColorBar(colorBar)); m_styleColorMenu->addSeparator(); @@ -1268,11 +1450,596 @@ void ScintillaEditView::contextUserDefineMenuEvent(QMenu* menu) m_styleColorMenu->addAction(tr("Clear All"), m_NoteWin, &CCNotePad::slot_clearMark); } menu->addMenu(m_styleColorMenu); + + menu->addSeparator(); + + menu->addAction(tr("Add/Del line comment"), [this]() { + doBlockComment(cm_toggle); + }); + menu->addAction(tr("Add Block comment"), [this]() { + doStreamComment(); + }); + menu->addAction(tr("Del Block comment"), [this]() { + undoStreamComment(); + }); } menu->show(); } +void ScintillaEditView::replaceSelWith(const char* replaceText) +{ + execute(SCI_REPLACESEL, 0, reinterpret_cast(replaceText)); +} + +bool ScintillaEditView::doBlockComment(Comment_Mode currCommentMode) +{ + if (this->isReadOnly()) + { + return false; + } + + //-- BlockToStreamComment: + QByteArray commentStart; + QByteArray commentEnd; + + QByteArray symbolStart; + QByteArray symbolEnd; + + QByteArray commentLineSymbol; + QByteArray symbol; + + + bool isSingleLineAdvancedMode = false; + QsciLexer* pLexer = this->lexer(); + + if (pLexer == nullptr) + { + return false; + } + else + { + commentLineSymbol = pLexer->getCommentLineSymbol(); + commentStart = pLexer->getCommentStart(); + commentEnd = pLexer->getCommentEnd(); + } + + if ((commentLineSymbol.isEmpty()) || commentLineSymbol.isEmpty()) + { + // BlockToStreamComment: If there is no block-comment symbol, try the stream comment: + if (!(commentStart.isEmpty() || commentEnd.isEmpty())) + { + if (currCommentMode == cm_comment) + { + isSingleLineAdvancedMode = true; + + } + else if (currCommentMode == cm_uncomment) + { + return undoStreamComment(false); + } + else if (currCommentMode == cm_toggle) + { + isSingleLineAdvancedMode = true; + } + else + { + return false; + } + } + else + { + return false; + } + } + + //For Single Line NORMAL MODE + QByteArray comment; + size_t comment_length = 0; + + //For Single Line ADVANCED MODE + QByteArray advCommentStart; + QByteArray advCommentEnd; + size_t advCommentStart_length = 0; + size_t advCommentEnd_length = 0; + + QByteArray aSpace(" "); + + //Only values that have passed through will be assigned, to be sure they are valid! + if (!isSingleLineAdvancedMode) + { + comment = commentLineSymbol; + + if (!(pLexer->lexerId() == L_BAANC)) // BaanC standardization - no space. + { + comment += aSpace; + } + + comment_length = comment.length(); + } + else // isSingleLineAdvancedMode + { + advCommentStart = commentStart; + advCommentStart += aSpace; + advCommentEnd = aSpace; + advCommentEnd += commentEnd; + + advCommentStart_length = advCommentStart.length(); + advCommentEnd_length = advCommentEnd.length(); + } + + size_t selectionStart = this->execute(SCI_GETSELECTIONSTART); + size_t selectionEnd = this->execute(SCI_GETSELECTIONEND); + size_t caretPosition = this->execute(SCI_GETCURRENTPOS); + + bool move_caret = caretPosition < selectionEnd; + intptr_t selStartLine = this->execute(SCI_LINEFROMPOSITION, selectionStart); + intptr_t selEndLine = this->execute(SCI_LINEFROMPOSITION, selectionEnd); + intptr_t lines = selEndLine - selStartLine; + + if ((lines > 0) && (selectionEnd == static_cast(this->execute(SCI_POSITIONFROMLINE, selEndLine)))) + { + selEndLine--; + } + + // count lines which were un-commented to decide if undoStreamComment() shall be called. + int nUncomments = 0; + //Some Lexers need line-comments at the beginning of a line. + const bool avoidIndent = (pLexer->lexerId() == L_FORTRAN_77 || pLexer->lexerId() == L_BAANC); + //Some Lexers comment blank lines, per their standards. + const bool commentEmptyLines = (pLexer->lexerId() == L_BAANC); + + this->execute(SCI_BEGINUNDOACTION); + + for (intptr_t i = selStartLine; i <= selEndLine; ++i) + { + size_t lineStart = this->execute(SCI_POSITIONFROMLINE, i); + size_t lineIndent = this->execute(SCI_GETLINEINDENTPOSITION, i); + size_t lineEnd = this->execute(SCI_GETLINEENDPOSITION, i); + + // empty lines are not commented, unless required by the language. + if (lineIndent == lineEnd && !commentEmptyLines) + continue; + + if (avoidIndent) + lineIndent = lineStart; + + size_t linebufferSize = lineEnd - lineIndent + 1; + QByteArray linebuf; + linebuf.resize(linebufferSize); + this->getText(linebuf.data(), lineIndent, lineEnd); + + QByteArray linebufStr = linebuf; + + if (currCommentMode != cm_comment) // uncomment/toggle + { + if (!isSingleLineAdvancedMode) + { + if (qstrncmp(linebufStr.data(), comment.data(), !(pLexer->lexerId() == L_BAANC) ? comment_length - 1 : comment_length) == 0) + { + size_t len = (linebufStr[(int)comment_length - 1] == aSpace[0]) ? comment_length : (!(pLexer->lexerId() == L_BAANC) ? comment_length - 1 : comment_length); + + this->execute(SCI_SETSEL, lineIndent, lineIndent + len); + this->replaceSelWith(""); + + // SELECTION RANGE ADJUSTMENT ....................... + if (i == selStartLine) // first selected line + { + if (selectionStart > lineIndent + len) + selectionStart -= len; + else if (selectionStart > lineIndent) + selectionStart = lineIndent; + } // ................................................ + if (i == selEndLine) // last selected line + { + if (selectionEnd > lineIndent + len) + selectionEnd -= len; + else if (selectionEnd > lineIndent) + { + selectionEnd = lineIndent; + if (lineIndent == lineStart && i != selStartLine) + ++selectionEnd; // avoid caret return in this case + } + } // ................................................ + else // every iteration except the last selected line + selectionEnd -= len; + // .................................................. + + ++nUncomments; + continue; + } + } + else // isSingleLineAdvancedMode + { + if ((qstrncmp(linebufStr.data(), advCommentStart.data(), advCommentStart_length - 1) == 0) && + (qstrncmp(linebufStr.mid(linebufStr.length() - advCommentEnd_length + 1, advCommentEnd_length - 1).data(), advCommentEnd.mid(1, advCommentEnd_length - 1).data(), advCommentEnd_length - 1) == 0)) + { + size_t startLen = linebufStr[(int)advCommentStart_length - 1] == aSpace[0] ? advCommentStart_length : advCommentStart_length - 1; + size_t endLen = linebufStr[int(linebufStr.length() - advCommentEnd_length)] == aSpace[0] ? advCommentEnd_length : advCommentEnd_length - 1; + + this->execute(SCI_SETSEL, lineIndent, lineIndent + startLen); + this->replaceSelWith(""); + this->execute(SCI_SETSEL, lineEnd - startLen - endLen, lineEnd - startLen); + this->replaceSelWith(""); + + // SELECTION RANGE ADJUSTMENT ....................... + if (i == selStartLine) // first selected line + { + if (selectionStart > lineEnd - endLen) + selectionStart = lineEnd - startLen - endLen; + else if (selectionStart > lineIndent + startLen) + selectionStart -= startLen; + else if (selectionStart > lineIndent) + selectionStart = lineIndent; + } // ................................................ + if (i == selEndLine) // last selected line + { + if (selectionEnd > lineEnd) + selectionEnd -= (startLen + endLen); + else if (selectionEnd > lineEnd - endLen) + selectionEnd = lineEnd - startLen - endLen; + else if (selectionEnd > lineIndent + startLen) + selectionEnd -= startLen; + else if (selectionEnd > lineIndent) + { + selectionEnd = lineIndent; + if (lineIndent == lineStart && i != selStartLine) + ++selectionEnd; // avoid caret return in this case + } + } // ................................................ + else // every iteration except the last selected line + selectionEnd -= (startLen + endLen); + // .................................................. + + ++nUncomments; + continue; + } + } + } // uncomment/toggle + + if (currCommentMode != cm_uncomment) // comment/toggle + { + if (!isSingleLineAdvancedMode) + { + this->insertCharsFrom(lineIndent, comment); + + // SELECTION RANGE ADJUSTMENT ....................... + if (i == selStartLine) // first selected line + { + if (selectionStart >= lineIndent) + selectionStart += comment_length; + } // ................................................ + if (i == selEndLine) // last selected line + { + if (selectionEnd >= lineIndent) + selectionEnd += comment_length; + } // ................................................ + else // every iteration except the last selected line + selectionEnd += comment_length; + // .................................................. + } + else // isSingleLineAdvancedMode + { + this->insertCharsFrom(lineIndent, advCommentStart); + this->insertCharsFrom(lineEnd + advCommentStart_length, advCommentEnd); + + // SELECTION RANGE ADJUSTMENT ....................... + if (i == selStartLine) // first selected line + { + if (selectionStart >= lineIndent) + selectionStart += advCommentStart_length; + } // ................................................ + if (i == selEndLine) // last selected line + { + if (selectionEnd > lineEnd) + selectionEnd += (advCommentStart_length + advCommentEnd_length); + else if (selectionEnd >= lineIndent) + selectionEnd += advCommentStart_length; + } // ................................................ + else // every iteration except the last selected line + selectionEnd += (advCommentStart_length + advCommentEnd_length); + // .................................................. + } + } // comment/toggle + } // for (...) + + if (move_caret) + { + // moving caret to the beginning of selected block + this->execute(SCI_GOTOPOS, selectionEnd); + this->execute(SCI_SETCURRENTPOS, selectionStart); + } + else + { + this->execute(SCI_SETSEL, selectionStart, selectionEnd); + } + this->execute(SCI_ENDUNDOACTION); + + // undoStreamComment: If there were no block-comments to un-comment try uncommenting of stream-comment. + if ((currCommentMode == cm_uncomment) && (nUncomments == 0)) + { + return undoStreamComment(false); + } + return true; +} + +bool ScintillaEditView::undoStreamComment(bool tryBlockComment) +{ + QByteArray commentStart; + QByteArray commentEnd; + QByteArray commentLineSymbol; + + QByteArray symbolStart; + QByteArray symbolEnd; + QByteArray symbol; + + const int charbufLen = 10; + QByteArray charbuf; + charbuf.reserve(charbufLen); + + bool retVal = false; + + QsciLexer* pLexer = this->lexer(); + //-- Avoid side-effects (e.g. cursor moves number of comment-characters) when file is read-only. + if (this->isReadOnly()) + return false; + + if (pLexer->lexer() == nullptr) + { + return false; + } + else + { + commentLineSymbol = pLexer->getCommentLineSymbol(); + commentStart = pLexer->getCommentStart(); + commentEnd = pLexer->getCommentEnd(); + } + + + // BlockToStreamComment: If there is no stream-comment symbol and we came not from doBlockComment, try the block comment: + if (commentStart.isEmpty() || commentEnd.isEmpty()) + { + if (!(commentLineSymbol.isEmpty() && tryBlockComment)) + return doBlockComment(cm_uncomment); + else + return false; + } + + QByteArray start_comment(commentStart); + QByteArray end_comment(commentEnd); + QByteArray white_space(" "); + size_t start_comment_length = start_comment.length(); + size_t end_comment_length = end_comment.length(); + + // do as long as stream-comments are within selection + do + { + auto selectionStart = this->execute(SCI_GETSELECTIONSTART); + auto selectionEnd = this->execute(SCI_GETSELECTIONEND); + auto caretPosition = this->execute(SCI_GETCURRENTPOS); + auto docLength = this->execute(SCI_GETLENGTH); + + // checking if caret is located in _beginning_ of selected block + bool move_caret = caretPosition < selectionEnd; + + //-- Note: The caretPosition is either at selectionEnd or at selectionStart!! selectionStart is always before (smaller) than selectionEnd!! + + //-- First, search all start_comment and end_comment before and after the selectionStart and selectionEnd position. + const int iSelStart = 0, iSelEnd = 1; + const size_t N_CMNT = 2; + intptr_t posStartCommentBefore[N_CMNT], posEndCommentBefore[N_CMNT], posStartCommentAfter[N_CMNT], posEndCommentAfter[N_CMNT]; + bool blnStartCommentBefore[N_CMNT], blnEndCommentBefore[N_CMNT], blnStartCommentAfter[N_CMNT], blnEndCommentAfter[N_CMNT]; + intptr_t posStartComment, posEndComment; + intptr_t selectionStartMove, selectionEndMove; + int flags; + + //-- Directly use Scintilla-Functions + // rather than _findReplaceDlg.processFindNext()which does not return the find-position and is not quiet! + flags = SCFIND_WORDSTART; + this->execute(SCI_SETSEARCHFLAGS, flags); + //-- Find all start- and end-comments before and after the selectionStart position. + //-- When searching upwards the start-position for searching must be moved one after the current position + // to find a search-string just starting before the current position! + //-- Direction DIR_UP --- + posStartCommentBefore[iSelStart] = this->searchInTarget(start_comment, selectionStart, 0); + (posStartCommentBefore[iSelStart] == -1 ? blnStartCommentBefore[iSelStart] = false : blnStartCommentBefore[iSelStart] = true); + posEndCommentBefore[iSelStart] = this->searchInTarget(end_comment, selectionStart, 0); + (posEndCommentBefore[iSelStart] == -1 ? blnEndCommentBefore[iSelStart] = false : blnEndCommentBefore[iSelStart] = true); + //-- Direction DIR_DOWN --- + posStartCommentAfter[iSelStart] = this->searchInTarget(start_comment, selectionStart, docLength); + (posStartCommentAfter[iSelStart] == -1 ? blnStartCommentAfter[iSelStart] = false : blnStartCommentAfter[iSelStart] = true); + posEndCommentAfter[iSelStart] = this->searchInTarget(end_comment, selectionStart, docLength); + (posEndCommentAfter[iSelStart] == -1 ? blnEndCommentAfter[iSelStart] = false : blnEndCommentAfter[iSelStart] = true); + + //-- Check, if selectionStart or selectionEnd is within a stream comment ----- + // or if the selection includes a complete stream-comment!! ---------------- + + //-- First, check if there is a stream-comment around the selectionStart position: + if ((blnStartCommentBefore[iSelStart] && blnEndCommentAfter[iSelStart]) + && (!blnEndCommentBefore[iSelStart] || (posStartCommentBefore[iSelStart] >= posEndCommentBefore[iSelStart])) + && (!blnStartCommentAfter[iSelStart] || (posEndCommentAfter[iSelStart] <= posStartCommentAfter[iSelStart]))) + { + posStartComment = posStartCommentBefore[iSelStart]; + posEndComment = posEndCommentAfter[iSelStart]; + } + else //-- Second, check if there is a stream-comment around the selectionEnd position: + { + //-- Find all start- and end-comments before and after the selectionEnd position. + //-- Direction DIR_UP --- + posStartCommentBefore[iSelEnd] = this->searchInTarget(start_comment, selectionEnd, 0); + (posStartCommentBefore[iSelEnd] == -1 ? blnStartCommentBefore[iSelEnd] = false : blnStartCommentBefore[iSelEnd] = true); + posEndCommentBefore[iSelEnd] = this->searchInTarget(end_comment, selectionEnd, 0); + (posEndCommentBefore[iSelEnd] == -1 ? blnEndCommentBefore[iSelEnd] = false : blnEndCommentBefore[iSelEnd] = true); + //-- Direction DIR_DOWN --- + posStartCommentAfter[iSelEnd] = this->searchInTarget(start_comment, selectionEnd, docLength); + (posStartCommentAfter[iSelEnd] == -1 ? blnStartCommentAfter[iSelEnd] = false : blnStartCommentAfter[iSelEnd] = true); + posEndCommentAfter[iSelEnd] = this->searchInTarget(end_comment, selectionEnd, docLength); + (posEndCommentAfter[iSelEnd] == -1 ? blnEndCommentAfter[iSelEnd] = false : blnEndCommentAfter[iSelEnd] = true); + + if ((blnStartCommentBefore[iSelEnd] && blnEndCommentAfter[iSelEnd]) + && (!blnEndCommentBefore[iSelEnd] || (posStartCommentBefore[iSelEnd] >= posEndCommentBefore[iSelEnd])) + && (!blnStartCommentAfter[iSelEnd] || (posEndCommentAfter[iSelEnd] <= posStartCommentAfter[iSelEnd]))) + { + posStartComment = posStartCommentBefore[iSelEnd]; + posEndComment = posEndCommentAfter[iSelEnd]; + } + //-- Third, check if there is a stream-comment within the selected area: + else if ((blnStartCommentAfter[iSelStart] && (posStartCommentAfter[iSelStart] < selectionEnd)) + && (blnEndCommentBefore[iSelEnd] && (posEndCommentBefore[iSelEnd] > selectionStart))) + { + //-- If there are more than one stream-comment within the selection, take the first one after selectionStart!! + posStartComment = posStartCommentAfter[iSelStart]; + posEndComment = posEndCommentAfter[iSelStart]; + } + //-- Finally, if there is no stream-comment, return + else + return retVal; + } + + //-- Ok, there are valid start-comment and valid end-comment around the caret-position. + // Now, un-comment stream-comment: + retVal = true; + intptr_t startCommentLength = start_comment_length; + intptr_t endCommentLength = end_comment_length; + + //-- First delete end-comment, so that posStartCommentBefore does not change! + //-- Get character before end-comment to decide, if there is a white character before the end-comment, which will be removed too! + this->getText(charbuf.data(), posEndComment - 1, posEndComment); + if (qstrncmp(charbuf, white_space, white_space.length()) == 0) + { + endCommentLength += 1; + posEndComment -= 1; + } + //-- Delete end stream-comment string --------- + this->execute(SCI_BEGINUNDOACTION); + this->execute(SCI_SETSEL, posEndComment, posEndComment + endCommentLength); + this->execute(SCI_REPLACESEL, 0, reinterpret_cast("")); + + //-- Get character after start-comment to decide, if there is a white character after the start-comment, which will be removed too! + this->getText(charbuf.data(), posStartComment + startCommentLength, posStartComment + startCommentLength + 1); + if (qstrncmp(charbuf, white_space, white_space.length()) == 0) + startCommentLength += 1; + + //-- Delete starting stream-comment string --------- + this->execute(SCI_SETSEL, posStartComment, posStartComment + startCommentLength); + this->execute(SCI_REPLACESEL, 0, reinterpret_cast("")); + this->execute(SCI_ENDUNDOACTION); + + //-- Reset selection before calling the routine + //-- Determine selection movement + // selectionStart + if (selectionStart > posStartComment) + { + if (selectionStart >= posStartComment + startCommentLength) + selectionStartMove = -startCommentLength; + else + selectionStartMove = -selectionStart - posStartComment; + } + else + selectionStartMove = 0; + + // selectionEnd + if (selectionEnd >= posEndComment + endCommentLength) + selectionEndMove = -startCommentLength + endCommentLength; + else if (selectionEnd <= posEndComment) + selectionEndMove = -startCommentLength; + else + selectionEndMove = -startCommentLength + (selectionEnd - posEndComment); + + //-- Reset selection of text without deleted stream-comment-string + if (move_caret) + { + // moving caret to the beginning of selected block + this->execute(SCI_GOTOPOS, selectionEnd + selectionEndMove); + this->execute(SCI_SETCURRENTPOS, selectionStart + selectionStartMove); + } + else + { + this->execute(SCI_SETSEL, selectionStart + selectionStartMove, selectionEnd + selectionEndMove); + } + } while (1); //do as long as stream-comments are within selection +} + +bool ScintillaEditView::doStreamComment() +{ + QByteArray commentStart; + QByteArray commentEnd; + + QByteArray symbolStart; + QByteArray symbolEnd; + + // BlockToStreamComment: + QByteArray commentLineSymbol; + QByteArray symbol; + + + if (this->isReadOnly()) + return false; + + QsciLexer* pLexer = this->lexer(); + + if (pLexer == nullptr) + { + return false; + } + else + { + // BlockToStreamComment: Next line needed to decide, if block-comment can be called below! + commentLineSymbol = pLexer->getCommentLineSymbol(); + commentStart = pLexer->getCommentStart(); + commentEnd = pLexer->getCommentEnd(); + } + + // BlockToStreamComment: If there is no stream-comment symbol, try the block comment: + if (commentStart.isEmpty()||commentEnd.isEmpty()) + { + if (!commentLineSymbol.isEmpty()) + return doBlockComment(cm_comment); + else + { + return false; + } + } + + QByteArray start_comment(commentStart); + QByteArray end_comment(commentEnd); + QByteArray white_space(" "); + + start_comment += white_space; + white_space += end_comment; + end_comment = white_space; + size_t start_comment_length = start_comment.length(); + size_t selectionStart = this->execute(SCI_GETSELECTIONSTART); + size_t selectionEnd = this->execute(SCI_GETSELECTIONEND); + size_t caretPosition = this->execute(SCI_GETCURRENTPOS); + // checking if caret is located in _beginning_ of selected block + bool move_caret = caretPosition < selectionEnd; + + // if there is no selection? + if (selectionEnd - selectionStart <= 0) + { + auto selLine = this->execute(SCI_LINEFROMPOSITION, selectionStart); + selectionStart = this->execute(SCI_GETLINEINDENTPOSITION, selLine); + selectionEnd = this->execute(SCI_GETLINEENDPOSITION, selLine); + } + this->execute(SCI_BEGINUNDOACTION); + this->insertCharsFrom(selectionStart, start_comment); + selectionEnd += start_comment_length; + selectionStart += start_comment_length; + this->insertCharsFrom(selectionEnd, end_comment); + if (move_caret) + { + // moving caret to the beginning of selected block + this->execute(SCI_GOTOPOS, selectionEnd); + this->execute(SCI_SETCURRENTPOS, selectionStart); + } + else + { + this->execute(SCI_SETSEL, selectionStart, selectionEnd); + } + this->execute(SCI_ENDUNDOACTION); + return true; +} void ScintillaEditView::slot_delayWork() { @@ -1313,6 +2080,42 @@ void ScintillaEditView::dropEvent(QDropEvent* e) void ScintillaEditView::mouseDoubleClickEvent(QMouseEvent * e) { + if (CCNotePad::s_hightWebAddr == 1) + { + do { + int position = this->execute(SCI_GETCURRENTPOS); + + auto indicMsk = this->execute(SCI_INDICATORALLONFOR, position); + if (!(indicMsk & (1 << URL_INDIC))) + break; + + auto startPos = this->execute(SCI_INDICATORSTART, URL_INDIC, position); + auto endPos = this->execute(SCI_INDICATOREND, URL_INDIC, position); + + if ((position < startPos) || (position > endPos)) + break; + + // WM_LBUTTONUP goes to opening browser instead of Scintilla here, because the mouse is not captured. + // The missing message causes mouse cursor flicker as soon as the mouse cursor is moved to a position outside the text editing area. + //::PostMessage(this->getHSelf(), WM_LBUTTONUP, 0, 0); + + // Revert selection of current word. Best to this early, otherwise the + // selected word is visible all the time while the browser is starting + execute(SCI_SETSEL, position, position); + + // Open URL + QByteArray url; + url.resize(endPos - startPos); + this->getText(url.data(), static_cast(startPos), static_cast(endPos)); + QUrl urlweb(url); + if (urlweb.isValid()) + { + QDesktopServices::openUrl(urlweb); + return; + } + } while (0); + } + QsciScintilla::mouseDoubleClickEvent(e); if (hasSelectedText()) @@ -1720,18 +2523,596 @@ void ScintillaEditView::sortLines(size_t fromLine, size_t toLine, ISorter* pSort } } -void ScintillaEditView::setFoldColor(int margin, QColor fgClack, QColor bkColor) +void ScintillaEditView::setFoldColor(int margin, QColor fgClack, QColor bkColor, QColor foreActive) { SendScintilla(SCI_MARKERSETFORE, margin, fgClack); SendScintilla(SCI_MARKERSETBACK, margin, bkColor); + SendScintilla(SCI_MARKERSETBACKSELECTED, margin, foreActive); +} + +ColumnModeInfos ScintillaEditView::getColumnModeSelectInfo() +{ + ColumnModeInfos columnModeInfos; + if (execute(SCI_GETSELECTIONS) > 1) // Multi-Selection || Column mode + { + intptr_t nbSel = execute(SCI_GETSELECTIONS); + + for (int i = 0; i < nbSel; ++i) + { + intptr_t absPosSelStartPerLine = execute(SCI_GETSELECTIONNANCHOR, i); + intptr_t absPosSelEndPerLine = execute(SCI_GETSELECTIONNCARET, i); + intptr_t nbVirtualAnchorSpc = execute(SCI_GETSELECTIONNANCHORVIRTUALSPACE, i); + intptr_t nbVirtualCaretSpc = execute(SCI_GETSELECTIONNCARETVIRTUALSPACE, i); + + if (absPosSelStartPerLine == absPosSelEndPerLine && execute(SCI_SELECTIONISRECTANGLE)) + { + bool dir = nbVirtualAnchorSpc < nbVirtualCaretSpc ? L2R : R2L; + columnModeInfos.push_back(ColumnModeInfo(absPosSelStartPerLine, absPosSelEndPerLine, i, dir, nbVirtualAnchorSpc, nbVirtualCaretSpc)); + } + else if (absPosSelStartPerLine > absPosSelEndPerLine) + columnModeInfos.push_back(ColumnModeInfo(absPosSelEndPerLine, absPosSelStartPerLine, i, R2L, nbVirtualAnchorSpc, nbVirtualCaretSpc)); + else + columnModeInfos.push_back(ColumnModeInfo(absPosSelStartPerLine, absPosSelEndPerLine, i, L2R, nbVirtualAnchorSpc, nbVirtualCaretSpc)); + } + } + return columnModeInfos; +} + + +void ScintillaEditView::columnReplace(ColumnModeInfos& cmi, QByteArray& str) +{ + intptr_t totalDiff = 0; + for (size_t i = 0, len = cmi.size(); i < len; ++i) + { + if (cmi[i].isValid()) + { + intptr_t len2beReplace = cmi[i]._selRpos - cmi[i]._selLpos; + intptr_t diff = str.size() - len2beReplace; + + cmi[i]._selLpos += totalDiff; + cmi[i]._selRpos += totalDiff; + bool hasVirtualSpc = cmi[i]._nbVirtualAnchorSpc > 0; + + if (hasVirtualSpc) // if virtual space is present, then insert space + { + for (intptr_t j = 0, k = cmi[i]._selLpos; j < cmi[i]._nbVirtualCaretSpc; ++j, ++k) + { + execute(SCI_INSERTTEXT, k, reinterpret_cast(" ")); + } + cmi[i]._selLpos += cmi[i]._nbVirtualAnchorSpc; + cmi[i]._selRpos += cmi[i]._nbVirtualCaretSpc; + } + + execute(SCI_SETTARGETRANGE, cmi[i]._selLpos, cmi[i]._selRpos); + + execute(SCI_REPLACETARGET, static_cast(-1), reinterpret_cast(str.data())); + + if (hasVirtualSpc) + { + totalDiff += cmi[i]._nbVirtualAnchorSpc + str.size(); + + // Now there's no more virtual space + cmi[i]._nbVirtualAnchorSpc = 0; + cmi[i]._nbVirtualCaretSpc = 0; + } + else + { + totalDiff += diff; + } + cmi[i]._selRpos += diff; + } + } +} + + +void ScintillaEditView::setMultiSelections(const ColumnModeInfos& cmi) +{ + for (size_t i = 0, len = cmi.size(); i < len; ++i) + { + if (cmi[i].isValid()) + { + intptr_t selStart = cmi[i]._direction == L2R ? cmi[i]._selLpos : cmi[i]._selRpos; + intptr_t selEnd = cmi[i]._direction == L2R ? cmi[i]._selRpos : cmi[i]._selLpos; + execute(SCI_SETSELECTIONNSTART, i, selStart); + execute(SCI_SETSELECTIONNEND, i, selEnd); + } + + if (cmi[i]._nbVirtualAnchorSpc) + execute(SCI_SETSELECTIONNANCHORVIRTUALSPACE, i, cmi[i]._nbVirtualAnchorSpc); + if (cmi[i]._nbVirtualCaretSpc) + execute(SCI_SETSELECTIONNCARETVIRTUALSPACE, i, cmi[i]._nbVirtualCaretSpc); + } +} + +int getNbDigits(int aNum, int base) +{ + int nbChiffre = 1; + int diviseur = base; + + for (;;) + { + int result = aNum / diviseur; + if (!result) + break; + else + { + diviseur *= base; + ++nbChiffre; + } + } + if ((base == 16) && (nbChiffre % 2 != 0)) + nbChiffre += 1; + + return nbChiffre; +} + +void ScintillaEditView::columnReplace(ColumnModeInfos& cmi, int initial, int incr, int repeat, int format, bool isCapital, QByteArray& prefix) +{ + assert(repeat > 0); + + // If there is no column mode info available, no need to do anything + // If required a message can be shown to user, that select column properly or something similar + // It is just a double check as taken in callee method (in case this method is called from multiple places) + if (cmi.size() <= 0) + return; + // 0000 00 00 : Dec BASE_10 + // 0000 00 01 : Hex BASE_16 + // 0000 00 10 : Oct BASE_08 + // 0000 00 11 : Bin BASE_02 + + // 0000 01 00 : 0 leading + + //Defined in ScintillaEditView.h : + //const UCHAR MASK_FORMAT = 0x03; + //const UCHAR MASK_ZERO_LEADING = 0x04; + + int base = format; + + const int stringSize = 512; + QByteArray str; + str.reserve(stringSize) ; + + // Compute the numbers to be placed at each column. + std::vector numbers; + { + int curNumber = initial; + const size_t kiMaxSize = cmi.size(); + while (numbers.size() < kiMaxSize) + { + for (int i = 0; i < repeat; i++) + { + numbers.push_back(curNumber); + if (numbers.size() >= kiMaxSize) + { + break; + } + } + curNumber += incr; + } + } + + assert(numbers.size() > 0); + + /*const int kibEnd = getNbDigits(*numbers.rbegin(), base); + const int kibInit = getNbDigits(initial, base); + const int kib = std::max(kibInit, kibEnd);*/ + + intptr_t totalDiff = 0; + const size_t len = cmi.size(); + for (size_t i = 0; i < len; i++) + { + if (cmi[i].isValid()) + { + const intptr_t len2beReplaced = cmi[i]._selRpos - cmi[i]._selLpos; + + if (base != 16) + { + str = prefix + QString::number(numbers.at(i), base).toUtf8(); + } + else + { + //16进制,判断大小写 + if (isCapital) + { + str = prefix + QString::number(numbers.at(i), base).toUpper().toUtf8(); + } + else + { + str = prefix + QString::number(numbers.at(i), base).toUtf8(); + } + } + + const intptr_t diff = str.size() - len2beReplaced; + + cmi[i]._selLpos += totalDiff; + cmi[i]._selRpos += totalDiff; + + + + const bool hasVirtualSpc = cmi[i]._nbVirtualAnchorSpc > 0; + if (hasVirtualSpc) // if virtual space is present, then insert space + { + for (intptr_t j = 0, k = cmi[i]._selLpos; j < cmi[i]._nbVirtualCaretSpc; ++j, ++k) + { + execute(SCI_INSERTTEXT, k, reinterpret_cast(" ")); + } + cmi[i]._selLpos += cmi[i]._nbVirtualAnchorSpc; + cmi[i]._selRpos += cmi[i]._nbVirtualCaretSpc; + } + execute(SCI_SETTARGETRANGE, cmi[i]._selLpos, cmi[i]._selRpos); + + execute(SCI_REPLACETARGET, static_cast(-1), reinterpret_cast(str.data())); + + if (hasVirtualSpc) + { + totalDiff += cmi[i]._nbVirtualAnchorSpc + str.size(); + // Now there's no more virtual space + cmi[i]._nbVirtualAnchorSpc = 0; + cmi[i]._nbVirtualCaretSpc = 0; + } + else + { + totalDiff += diff; + } + cmi[i]._selRpos += diff; + } + } +} + +void ScintillaEditView::getVisibleStartAndEndPosition(int * startPos, int * endPos) +{ + assert(startPos != NULL && endPos != NULL); + // Get the position of the 1st and last showing chars from the edit view + QRect rcEditView; + rcEditView = this->rect(); + int pos = execute(SCI_POSITIONFROMPOINT, 0, 0); + int line = execute(SCI_LINEFROMPOSITION, pos); + *startPos = static_cast(execute(SCI_POSITIONFROMLINE, line)); + pos = execute(SCI_POSITIONFROMPOINT, rcEditView.right() - rcEditView.left(), rcEditView.bottom() - rcEditView.top()); + line = execute(SCI_LINEFROMPOSITION, pos); + *endPos = static_cast(execute(SCI_GETLINEENDPOSITION, line)); +} + +bool isUrlSchemeStartChar(QChar const c) +{ + return ((c >= 'A') && (c <= 'Z')) + || ((c >= 'a') && (c <= 'z')); +} + +bool isUrlSchemeDelimiter(QChar const c) +{ + return !(((c >= '0') && (c <= '9')) + || ((c >= 'A') && (c <= 'Z')) + || ((c >= 'a') && (c <= 'z')) + || (c == '_')); +} + +bool scanToUrlStart(QString &text, int textLen, int start, int* distance, int* schemeLength) +{ + int p = start; + int p0 = 0; + enum { sUnknown, sScheme } s = sUnknown; + while (p < textLen) + { + switch (s) + { + case sUnknown: + if (isUrlSchemeStartChar(text[p]) && ((p == 0) || isUrlSchemeDelimiter(text[p - 1]))) + { + p0 = p; + s = sScheme; + } + break; + + case sScheme: + if (text[p] == ':') + { + *distance = p0 - start; + *schemeLength = p - p0 + 1; + return true; + } + if (!isUrlSchemeStartChar(text[p])) + s = sUnknown; + break; + } + p++; + } + *schemeLength = 0; + *distance = p - start; + return false; +} + +bool isUrlTextChar(QChar const c) +{ + if (c <= ' ') return false; + switch (c.digitValue()) + { + case ('"'): + case ('#'): + case ('<'): + case ('>'): + case ('{'): + case ('}'): + case ('?'): + case ('\u007F'): + return false; + } + return true; +} + +bool isUrlQueryDelimiter(QChar const c) +{ + switch (c.digitValue()) + { + case '&': + case '+': + case '=': + case ';': + return true; + } + return false; +} + +void scanToUrlEnd(QString & text, int textLen, int start, int* distance) +{ + int p = start; + QChar q = 0; + enum { sHostAndPath, sQuery, sQueryAfterDelimiter, sQueryQuotes, sQueryAfterQuotes, sFragment } s = sHostAndPath; + while (p < textLen) + { + switch (s) + { + case sHostAndPath: + if (text[p] == QChar('?')) + s = sQuery; + else if (text[p] == '#') + s = sFragment; + else if (!isUrlTextChar(text[p])) + { + *distance = p - start; + return; + } + break; + + case sQuery: + if (text[p] == '#') + s = sFragment; + else if (isUrlQueryDelimiter(text[p])) + s = sQueryAfterDelimiter; + else if (!isUrlTextChar(text[p])) + { + *distance = p - start; + return; + } + break; + + case sQueryAfterDelimiter: + if ((text[p] == '\'') || (text[p] == '"') || (text[p] == '`')) + { + q = text[p]; + s = sQueryQuotes; + } + else if (text[p] == '(') + { + q = ')'; + s = sQueryQuotes; + } + else if (text[p] == '[') + { + q = ']'; + s = sQueryQuotes; + } + else if (text[p] == '{') + { + q = '}'; + s = sQueryQuotes; + } + else if (isUrlTextChar(text[p])) + s = sQuery; + else + { + *distance = p - start; + return; + } + break; + + case sQueryQuotes: + if (text[p] < ' ') + { + *distance = p - start; + return; + } + if (text[p] == q) + s = sQueryAfterQuotes; + break; + + case sQueryAfterQuotes: + if (isUrlQueryDelimiter(text[p])) + s = sQueryAfterDelimiter; + else + { + *distance = p - start; + return; + } + break; + + case sFragment: + if (!isUrlTextChar(text[p])) + { + *distance = p - start; + return; + } + break; + } + p++; + } + *distance = p - start; +} + +// removeUnwantedTrailingCharFromUrl removes a single unwanted trailing character from an URL. +// It has to be called repeatedly, until it returns false, meaning that all unwanted characters are gone. +bool removeUnwantedTrailingCharFromUrl(QChar const *text, int* length) +{ + int l = *length - 1; + if (l <= 0) return false; + { // remove unwanted single characters + const char *singleChars = ".,:;?!#"; + for (int i = 0; singleChars[i]; i++) + if (text[l] == singleChars[i]) + { + *length = l; + return true; + } + } + { // remove unwanted closing parenthesis + const char *closingParenthesis = ")]"; + const char *openingParenthesis = "(["; + for (int i = 0; closingParenthesis[i]; i++) + if (text[l] == closingParenthesis[i]) + { + int count = 0; + for (int j = l - 1; j >= 0; j--) + { + if (text[j] == closingParenthesis[i]) + count++; + if (text[j] == openingParenthesis[i]) + if (count > 0) + count--; + else + return false; + } + if (count != 0) + return false; + *length = l; + return true; + } + } + return false; +} + +bool isUrl(QString& text, int textLen, int start, int* segmentLen) +{ + int dist = 0, schemeLen = 0; + if (scanToUrlStart(text, textLen, start, &dist, &schemeLen)) + { + if (dist) + { + *segmentLen = dist; + return false; + } + int len = 0; + scanToUrlEnd(text, textLen, start + schemeLen, &len); + if (len) + { + len += schemeLen; + + QString urlStr = text.mid(start, len); + if (urlStr.startsWith("http://") || urlStr.startsWith("https://")) + { + + QUrl url(urlStr); + + bool r = url.isValid(); + if (r) + { + while (removeUnwantedTrailingCharFromUrl(text.data() + start, &len)); + *segmentLen = len; + return true; + } + } + } + len = 1; + int lMax = textLen - start; + while (isUrlSchemeStartChar(text[start + len]) && (len < lMax)) len++; + *segmentLen = len; + return false; + } + *segmentLen = dist; + return false; +} + +void ScintillaEditView::addHotSpot() +{ + if (CCNotePad::s_hightWebAddr == 1) + { + int urlAction = urlNoUnderLineFg; + int indicStyle = INDIC_PLAIN; + int indicHoverStyle = INDIC_EXPLORERLINK; + int indicStyleCur = this->execute(SCI_INDICGETSTYLE, URL_INDIC); + int indicHoverStyleCur = this->execute(SCI_INDICGETHOVERSTYLE, URL_INDIC); + + if ((indicStyleCur != indicStyle) || (indicHoverStyleCur != indicHoverStyle)) + { + this->execute(SCI_INDICSETSTYLE, URL_INDIC, indicStyle); + this->execute(SCI_INDICSETHOVERSTYLE, URL_INDIC, indicHoverStyle); + this->execute(SCI_INDICSETALPHA, URL_INDIC, 70); + this->execute(SCI_INDICSETFLAGS, URL_INDIC, SC_INDICFLAG_VALUEFORE); + } + + int startPos = 0; + int endPos = -1; + this->getVisibleStartAndEndPosition(&startPos, &endPos); + if (startPos >= endPos) + { + return; + } + + this->execute(SCI_SETINDICATORCURRENT, URL_INDIC); + if (urlAction == urlDisable) + { + this->execute(SCI_INDICATORCLEARRANGE, startPos, endPos - startPos); + return; + } + + int indicFore = this->execute(SCI_STYLEGETFORE, STYLE_DEFAULT); + this->execute(SCI_SETINDICATORVALUE, indicFore); + + QByteArray encodedText; + encodedText.resize(endPos - startPos); + this->getText(encodedText.data(), startPos, endPos); + + QString encodedTextStr(encodedText); + + int wideTextLen = encodedTextStr.size(); + + + if (wideTextLen > 0) + { + int startWide = 0; + int lenWide = 0; + int startEncoded = 0; + int lenEncoded = 0; + while (true) + { + bool r = isUrl(encodedTextStr, encodedTextStr.size(), startWide, &lenWide); + if (lenWide <= 0) + break; + + lenEncoded = encodedTextStr.mid(startWide, lenWide).toUtf8().size(); + + if (r) + this->execute(SCI_INDICATORFILLRANGE, startEncoded + startPos, lenEncoded); + else + this->execute(SCI_INDICATORCLEARRANGE, startEncoded + startPos, lenEncoded); + + startWide += lenWide; + startEncoded += lenEncoded; + + if ((startWide >= wideTextLen) || ((startEncoded + startPos) >= endPos)) + break; + } + assert((startEncoded + startPos) == endPos); + assert(startWide == wideTextLen); + } + } } void ScintillaEditView::setStyleOptions() { +#if 0 //如果是黑色主题,则单独做一些风格设置 if (StyleSet::m_curStyleId == BLACK_SE) { - //setCaretLineBackgroundColor(QColor(0x3f3f12)); setCaretLineBackgroundColor(QColor(0x333333)); setMatchedBraceForegroundColor(QColor(246, 81, 246)); setMatchedBraceBackgroundColor(QColor(18, 90, 36)); @@ -1758,4 +3139,426 @@ void ScintillaEditView::setStyleOptions() setFoldColor(SC_MARKNUM_FOLDEROPENMID, QColor(Qt::white), QColor(128, 128, 128)); setFoldColor(SC_MARKNUM_FOLDERMIDTAIL, QColor(Qt::white), QColor(128, 128, 128)); } +#endif +} + +//在ScintillaEditView中直接设置这些One_Stype_Info的属性值 +//这里的style不一定是在lexer中的,而是默认的STYLE_*自定义的那些全局内部风格。 +void ScintillaEditView::updateThemes() +{ + //第0个是GLOBAL_OVERRIDE,是Lexer的样式,不属于全局 + for (int i = 1; i <= URL_HOVERRED; ++i) + { + setGlobalFgColor(i); + setGlobalBgColor(i); + setGlobalFont(i); + } +} + +void getFoldColor(QColor& fgColor, QColor& bgColor, QColor& activeFgColor) +{ + //这里看起来反了,但是实际代码就是如此 + fgColor = StyleSet::s_global_style->fold.bgColor; + bgColor = StyleSet::s_global_style->fold.fgColor; + + activeFgColor = StyleSet::s_global_style->fold_active.fgColor; + +} + +void ScintillaEditView::setGlobalFgColor(int style) +{ + switch (style) + { + case GLOBAL_OVERRIDE: + { + //全局前景色修改,是针对语法的lexer属性进行的修改,而非其余全局属性的修改。这点要区分开来 + } + break; + + case DEFAULT_STYLE: + { + //修改默认前景色 + SendScintilla(SCI_STYLESETFORE, StyleSet::s_global_style->default_style.styleId, StyleSet::s_global_style->default_style.fgColor); + } + break; + + case INDENT_GUIDELINE: + { + //修改默认前景色 + SendScintilla(SCI_STYLESETFORE, StyleSet::s_global_style->indent_guideline.styleId, StyleSet::s_global_style->indent_guideline.fgColor); + } + break; + + case BRACE_HIGHIGHT: + { + //修改默认前景色 + SendScintilla(SCI_STYLESETFORE, StyleSet::s_global_style->brace_highight.styleId, StyleSet::s_global_style->brace_highight.fgColor); + } + break; + + case BAD_BRACE_COLOUR: + { + //修改默认前景色 + SendScintilla(SCI_STYLESETFORE, StyleSet::s_global_style->bad_brace_color.styleId, StyleSet::s_global_style->bad_brace_color.fgColor); + } + break; + + case CURRENT_LINE_BACKGROUND_COLOR: + //不能设置前景色,只能设置背景 + break; + + case SELECT_TEXT_COLOR: + SendScintilla(SCI_SETSELFORE, true, StyleSet::s_global_style->select_text_color.fgColor); + break; + + case CARET_COLOUR: + SendScintilla(SCI_SETCARETFORE, StyleSet::s_global_style->caret_colour.fgColor); + break; + + case EDGE_COLOUR: + SendScintilla(SCI_SETEDGECOLOUR, StyleSet::s_global_style->edge_colour.fgColor); + break; + + case LINE_NUMBER_MARGIN: + { + //修改默认前景色 + SendScintilla(SCI_STYLESETFORE, StyleSet::s_global_style->line_number_margin.styleId, StyleSet::s_global_style->line_number_margin.fgColor); + } + break; + + case BOOKMARK_MARGIN: + //不能设置 + break; + + case FOLD: + case FOLD_ACTIVE: + { + QColor foldfgColor = Qt::white, foldbgColor = Qt::gray, activeFoldFgColor = Qt::red; + getFoldColor(foldfgColor, foldbgColor, activeFoldFgColor); + + setFoldColor(SC_MARKNUM_FOLDEROPEN, foldfgColor, foldbgColor, activeFoldFgColor); + setFoldColor(SC_MARKNUM_FOLDER, foldfgColor, foldbgColor, activeFoldFgColor); + setFoldColor(SC_MARKNUM_FOLDERSUB, foldfgColor, foldbgColor, activeFoldFgColor); + setFoldColor(SC_MARKNUM_FOLDERTAIL, foldfgColor, foldbgColor, activeFoldFgColor); + setFoldColor(SC_MARKNUM_FOLDEREND, foldfgColor, foldbgColor, activeFoldFgColor); + setFoldColor(SC_MARKNUM_FOLDEROPENMID, foldfgColor, foldbgColor, activeFoldFgColor); + setFoldColor(SC_MARKNUM_FOLDERMIDTAIL, foldfgColor, foldbgColor, activeFoldFgColor); + + //暂时开启,看看后面是否有错误 + //execute(SCI_MARKERENABLEHIGHLIGHT, true); + } + break; + + case FOLD_MARGIN: + //前景背景一起设置,不分开 + { + setFoldMarginColors(StyleSet::s_global_style->fold_margin.fgColor, StyleSet::s_global_style->fold_margin.bgColor); + } + break; + + case WHITE_SPACE_SYMBOL: + SendScintilla(SCI_SETWHITESPACEFORE, true, StyleSet::s_global_style->white_space_stybol.fgColor); + break; + + case SMART_HIGHLIGHTING: + //只能设置前景,不能设置背景 + SendScintilla(SCI_INDICSETFORE, SCE_UNIVERSAL_FOUND_STYLE_SMART, StyleSet::s_global_style->smart_highlighting.fgColor); + break; + + case FIND_MARK_STYLE: + //只能设置前景,不能设置背景。目前这条是空的,暂时没有使用 + SendScintilla(SCI_INDICSETFORE, SCE_UNIVERSAL_FOUND_STYLE, StyleSet::s_global_style->find_mark_style.fgColor); + break; + + case MARK_STYLE_1: + case MARK_STYLE_2: + case MARK_STYLE_3: + case MARK_STYLE_4: + case MARK_STYLE_5: + case INCREMENTAL_HIGHLIGHT: + //暂时没有使用 + break; + + case TAGS_MATCH_HIGHLIGHT: + SendScintilla(SCI_INDICSETFORE, SCE_UNIVERSAL_TAGMATCH, StyleSet::s_global_style->tags_match_highlight.fgColor); + break; + + case TAGS_ATTRIBUTE: + SendScintilla(SCI_INDICSETFORE, SCE_UNIVERSAL_TAGATTR, StyleSet::s_global_style->tags_attribute.fgColor); + break; + + //case ACTIVE_TAB_FOCUSED: + //case ACTIVE_TAB_UNFOCUSED: + //case ACTIVE_TAB_TEXT: + //case INACTIVE_TABS: + // break; + + case URL_HOVERRED: + SendScintilla(SCI_INDICSETHOVERFORE, URL_INDIC, StyleSet::s_global_style->url_hoverred.fgColor); + break; + + default: + break; + } +}; + +void ScintillaEditView::setGlobalBgColor(int style) +{ + switch (style) + { + case GLOBAL_OVERRIDE: + { + + } + break; + + case DEFAULT_STYLE: + { + //修改默认前景色 + SendScintilla(SCI_STYLESETBACK, StyleSet::s_global_style->default_style.styleId, StyleSet::s_global_style->default_style.bgColor); + } + break; + + case INDENT_GUIDELINE: + { + //修改默认前景色 + SendScintilla(SCI_STYLESETBACK, StyleSet::s_global_style->indent_guideline.styleId, StyleSet::s_global_style->indent_guideline.bgColor); + } + break; + + case BRACE_HIGHIGHT: + { + //修改默认前景色 + SendScintilla(SCI_STYLESETBACK, StyleSet::s_global_style->brace_highight.styleId, StyleSet::s_global_style->brace_highight.bgColor); + } + break; + + case BAD_BRACE_COLOUR: + { + //修改默认前景色 + SendScintilla(SCI_STYLESETBACK, StyleSet::s_global_style->bad_brace_color.styleId, StyleSet::s_global_style->bad_brace_color.bgColor); + } + break; + + case CURRENT_LINE_BACKGROUND_COLOR: + //不能设置前景色,只能设置背景 + SendScintilla(SCI_SETCARETLINEBACK, StyleSet::s_global_style->current_line_background_color.bgColor); + break; + + case SELECT_TEXT_COLOR: + SendScintilla(SCI_SETSELBACK, true, StyleSet::s_global_style->select_text_color.bgColor); + break; + + case CARET_COLOUR: + //不能设置 + break; + + case EDGE_COLOUR: + //不能设置 + break; + + case LINE_NUMBER_MARGIN: + { + //修改默认背景色 + SendScintilla(SCI_STYLESETBACK, StyleSet::s_global_style->line_number_margin.styleId, StyleSet::s_global_style->line_number_margin.bgColor); + } + break; + + case BOOKMARK_MARGIN: + { + if (StyleSet::s_global_style->bookmark_margin.bgColor.isValid()) + { + SendScintilla(SCI_SETMARGINBACKN, _SC_MARGE_SYBOLE, StyleSet::s_global_style->bookmark_margin.bgColor); + } + else + { + SendScintilla(SCI_SETMARGINBACKN, _SC_MARGE_SYBOLE, StyleSet::s_global_style->line_number_margin.bgColor); + } + } + break; + + case FOLD: + case FOLD_ACTIVE: + { + QColor foldfgColor = Qt::white, foldbgColor = Qt::gray, activeFoldFgColor = Qt::red; + getFoldColor(foldfgColor, foldbgColor, activeFoldFgColor); + + setFoldColor(SC_MARKNUM_FOLDEROPEN, foldfgColor, foldbgColor, activeFoldFgColor); + setFoldColor(SC_MARKNUM_FOLDER, foldfgColor, foldbgColor, activeFoldFgColor); + setFoldColor(SC_MARKNUM_FOLDERSUB, foldfgColor, foldbgColor, activeFoldFgColor); + setFoldColor(SC_MARKNUM_FOLDERTAIL, foldfgColor, foldbgColor, activeFoldFgColor); + setFoldColor(SC_MARKNUM_FOLDEREND, foldfgColor, foldbgColor, activeFoldFgColor); + setFoldColor(SC_MARKNUM_FOLDEROPENMID, foldfgColor, foldbgColor, activeFoldFgColor); + setFoldColor(SC_MARKNUM_FOLDERMIDTAIL, foldfgColor, foldbgColor, activeFoldFgColor); + + //暂时不能开启。因为QT下面有一个1Pix的差异,如果开启,当前fold的变化会缺失1pix的宽度,看起来难看。 + // 这是QT的bug,暂时解决不了。 + //execute(SCI_MARKERENABLEHIGHLIGHT, true); + } + break; + + case FOLD_MARGIN: + //前景背景一起设置,不分开 + { + setFoldMarginColors(StyleSet::s_global_style->fold_margin.fgColor, StyleSet::s_global_style->fold_margin.bgColor); + } + break; + + case WHITE_SPACE_SYMBOL: + //不能设置 + break; + + case SMART_HIGHLIGHTING: + //不能设置 + break; + + case FIND_MARK_STYLE: + //不能设置 + break; + + //下面五个比较特殊,选择改动的是背景。单本质改动的样式却是前景 + case MARK_STYLE_1: + //只能设置前景,不能设置背景 + SendScintilla(SCI_INDICSETFORE, SCE_UNIVERSAL_FOUND_STYLE_EXT5, StyleSet::s_global_style->mark_style_1.bgColor); + changeStyleColor(0); + break; + + case MARK_STYLE_2: + //只能设置前景,不能设置背景 + SendScintilla(SCI_INDICSETFORE, SCE_UNIVERSAL_FOUND_STYLE_EXT4, StyleSet::s_global_style->mark_style_2.bgColor); + changeStyleColor(1); + break; + + case MARK_STYLE_3: + //只能设置前景,不能设置背景 + SendScintilla(SCI_INDICSETFORE, SCE_UNIVERSAL_FOUND_STYLE_EXT3, StyleSet::s_global_style->mark_style_3.bgColor); + changeStyleColor(2); + break; + + case MARK_STYLE_4: + //只能设置前景,不能设置背景 + SendScintilla(SCI_INDICSETFORE, SCE_UNIVERSAL_FOUND_STYLE_EXT2, StyleSet::s_global_style->mark_style_4.bgColor); + changeStyleColor(3); + break; + + case MARK_STYLE_5: + //只能设置前景,不能设置背景 + SendScintilla(SCI_INDICSETFORE, SCE_UNIVERSAL_FOUND_STYLE_EXT1, StyleSet::s_global_style->mark_style_5.bgColor); + changeStyleColor(4); + break; + + case INCREMENTAL_HIGHLIGHT: + case TAGS_MATCH_HIGHLIGHT: + case TAGS_ATTRIBUTE: + break; + + //case ACTIVE_TAB_FOCUSED: + //case ACTIVE_TAB_UNFOCUSED: + //case ACTIVE_TAB_TEXT: + //case INACTIVE_TABS: + // break; + case URL_HOVERRED: + break; + default: + break; + } +}; + +// Set the font for a style. +//enum Font_Set_Bit { +// Bold_Bit = 0x1, +// Italic_Bit = 0x2, +// Underline_Bit = 0x4, +// Font_Name_Bit = 0x8, +// Font_Size_Bit = 0x10, +//}; +void ScintillaEditView::setStylesFont(const QFont& f, int style, int setBitMask) +{ + if (setBitMask & Font_Name_Bit) + { + SendScintilla(SCI_STYLESETFONT, style, f.family().toUtf8().data()); + } + if (setBitMask & Bold_Bit) + { + SendScintilla(SCI_STYLESETBOLD, style, f.bold()); + } + if (setBitMask & Italic_Bit) + { + SendScintilla(SCI_STYLESETITALIC, style, f.italic()); + } + if (setBitMask & Underline_Bit) + { + SendScintilla(SCI_STYLESETUNDERLINE, style, f.underline()); + } + + if (setBitMask & Font_Size_Bit && f.pointSize() > 2) + { + SendScintilla(SCI_STYLESETSIZE, style, f.pointSize()); + } + //如果是行号大小变化,则必须动态计算行宽度 + if (style == STYLE_LINENUMBER) + { + updateLineNumberWidth(1); + } +} + +void ScintillaEditView::setGlobalFont(int style) +{ + switch (style) + { + case GLOBAL_OVERRIDE: + case INDENT_GUIDELINE: + case CURRENT_LINE_BACKGROUND_COLOR: + case SELECT_TEXT_COLOR: + case CARET_COLOUR: + case EDGE_COLOUR: + case BOOKMARK_MARGIN: + case FOLD: + case FOLD_ACTIVE: + case FOLD_MARGIN: + case WHITE_SPACE_SYMBOL: + case SMART_HIGHLIGHTING: + case FIND_MARK_STYLE: + case MARK_STYLE_1: + case MARK_STYLE_2: + case MARK_STYLE_3: + case MARK_STYLE_4: + case MARK_STYLE_5: + case INCREMENTAL_HIGHLIGHT: + case TAGS_MATCH_HIGHLIGHT: + case TAGS_ATTRIBUTE: + //case ACTIVE_TAB_FOCUSED: + //case ACTIVE_TAB_UNFOCUSED: + //case ACTIVE_TAB_TEXT: + //case INACTIVE_TABS: + case URL_HOVERRED: + break; + + case DEFAULT_STYLE: + { + setStylesFont(StyleSet::s_global_style->default_style.font, STYLE_DEFAULT, 0x1f); + } + break; + + case BRACE_HIGHIGHT: + { + setStylesFont(StyleSet::s_global_style->brace_highight.font, STYLE_BRACELIGHT, 0x1f); + } + break; + + case BAD_BRACE_COLOUR: + { + setStylesFont(StyleSet::s_global_style->bad_brace_color.font, STYLE_BRACEBAD, 0x1f); + } + break; + + case LINE_NUMBER_MARGIN: + { + //除了下划线不加,其余的都需要设置 + setStylesFont(StyleSet::s_global_style->line_number_margin.font, STYLE_LINENUMBER, 0x1b); + } + break; + default: + break; + } } diff --git a/src/scintillaeditview.h b/src/scintillaeditview.h index 2453ccd..c97e110 100755 --- a/src/scintillaeditview.h +++ b/src/scintillaeditview.h @@ -47,6 +47,69 @@ enum TextCaseType RANDOMCASE }; +enum Comment_Mode +{ + cm_comment = 0, + cm_uncomment, + cm_toggle +}; +const bool L2R = true; +const bool R2L = false; + +struct ColumnModeInfo { + intptr_t _selLpos = 0; + intptr_t _selRpos = 0; + intptr_t _order = -1; // 0 based index + bool _direction = L2R; // L2R or R2L + intptr_t _nbVirtualCaretSpc = 0; + intptr_t _nbVirtualAnchorSpc = 0; + + ColumnModeInfo(intptr_t lPos, intptr_t rPos, intptr_t order, bool dir = L2R, intptr_t vAnchorNbSpc = 0, intptr_t vCaretNbSpc = 0) + : _selLpos(lPos), _selRpos(rPos), _order(order), _direction(dir), _nbVirtualAnchorSpc(vAnchorNbSpc), _nbVirtualCaretSpc(vCaretNbSpc) {}; + + bool isValid() const { + return (_order >= 0 && _selLpos >= 0 && _selRpos >= 0 && _selLpos <= _selRpos); + }; +}; + +struct SortInPositionOrder { + bool operator() (ColumnModeInfo& l, ColumnModeInfo& r) { + return (l._selLpos < r._selLpos); + } +}; + +struct SortInSelectOrder { + bool operator() (ColumnModeInfo& l, ColumnModeInfo& r) { + return (l._order < r._order); + } +}; + +typedef std::vector ColumnModeInfos; + +const int MASK_FORMAT = 0x03; +const int MASK_ZERO_LEADING = 0x04; +const int BASE_10 = 0x00; // Dec +const int BASE_16 = 0x01; // Hex +const int BASE_08 = 0x02; // Oct +const int BASE_02 = 0x03; // Bin + +#define URL_INDIC 8 + +enum urlMode { + urlDisable = 0, urlNoUnderLineFg, urlUnderLineFg, urlNoUnderLineBg, urlUnderLineBg, + urlMin = urlDisable, + urlMax = urlUnderLineBg +}; +#define INDIC_EXPLORERLINK 22 + +enum Font_Set_Bit { + Bold_Bit = 0x1, + Italic_Bit = 0x2, + Underline_Bit = 0x4, + Font_Name_Bit = 0x8, + Font_Size_Bit = 0x10, + ALL_SET_Bit = 0x1f, +}; class FindRecords; class CCNotePad; @@ -56,8 +119,8 @@ class ScintillaEditView : public QsciScintilla Q_OBJECT public: - ScintillaEditView(QWidget *parent); - ~ScintillaEditView(); + ScintillaEditView(QWidget *parent,bool isBigText = false); + virtual ~ScintillaEditView(); virtual void setLexer(QsciLexer *lexer = 0); @@ -65,7 +128,7 @@ public: //void resetDefaultFontStyle(); sptr_t execute(quint32 Msg, uptr_t wParam = 0, sptr_t lParam = 0) const; - static QsciLexer * createLexer(int lexerId, QString tag="", bool isOrigin=false); + static QsciLexer * createLexer(int lexerId, QString tag="", bool isOrigin=false, int styleId=-1); void appendMarkRecord(FindRecords *r); void releaseAllMark(); @@ -75,7 +138,7 @@ public: bool gotoNextPos(); - void adjuctSkinStyle(); + /*virtual void adjuctSkinStyle();*/ //设置文档的缩进参考线 void setIndentGuide(bool willBeShowed); @@ -122,9 +185,32 @@ public: //设置不同风格 void setStyleOptions(); + ColumnModeInfos getColumnModeSelectInfo(); + + void columnReplace(ColumnModeInfos& cmi, QByteArray& str); + + void setMultiSelections(const ColumnModeInfos& cmi); + + void columnReplace(ColumnModeInfos& cmi, int initial, int incr, int repeat, int format, bool isCapital, QByteArray& prefix); + + void setBigTextMode(bool isBigText); + void showBigTextLineAddr(qint64 fileOffset); + + void updateThemes(); + + //下面三个函数,是设置全局样式的接口。全局样式不同于每个语法中的样式 + void setGlobalFgColor(int style); + void setGlobalBgColor(int style); + void setGlobalFont(int style); + //void setGlobalFont(int style, const QFont& f,int stylePointSize = -1); signals: void delayWork(); +protected: + + virtual void addHotSpot(); + void setStylesFont(const QFont& f, int style, int setBitMask = ALL_SET_Bit); + private: void getText(char * dest, size_t start, size_t end) const; @@ -136,8 +222,13 @@ private: void appandGenericText(const QByteArray & text2Append) const; QString getMarkedLine(int ln); void deleteMarkedline(int ln); - void setFoldColor(int margin, QColor fgClack, QColor bkColor); - + void setFoldColor(int margin, QColor fgClack, QColor bkColor, QColor foreActive); + bool doBlockComment(Comment_Mode currCommentMode); + bool undoStreamComment(bool tryBlockComment = true); + bool doStreamComment(); + void getVisibleStartAndEndPosition(int * startPos, int * endPos); + void changeStyleColor(int sytleId); + void initStyleColorMenu(); public: static const int _SC_MARGE_LINENUMBER; @@ -154,6 +245,8 @@ protected: void mouseDoubleClickEvent(QMouseEvent *e) override; void contextUserDefineMenuEvent(QMenu * menu) override; + + public slots: void updateLineNumberWidth(int lineNumberMarginDynamicWidth=0); void slot_linePosChanged(int line, int pos); @@ -174,9 +267,10 @@ private: void slot_markColorGroup(QAction * action); + void replaceSelWith(const char* replaceText); private slots: void slot_delayWork(); - void slot_scrollXValueChange(int value); + void slot_scrollYValueChange(int value); void slot_clearHightWord(); void slot_bookMarkClicked(int margin, int line, Qt::KeyboardModifiers state); @@ -203,7 +297,9 @@ private: QPixmap* m_bookmarkPng; QMenu* m_styleColorMenu; + QList m_styleMarkActList; + bool m_isBigText;//大文本 public: static int s_tabLens; static bool s_noUseTab; diff --git a/src/scintillahexeditview.cpp b/src/scintillahexeditview.cpp index 03f7e40..94526ae 100755 --- a/src/scintillahexeditview.cpp +++ b/src/scintillahexeditview.cpp @@ -4,6 +4,7 @@ #include "ccnotepad.h" #include #include +#include // initialize the static variable bool ScintillaHexEditView::_SciInit = false; @@ -20,7 +21,11 @@ ScintillaHexEditView::~ScintillaHexEditView() void ScintillaHexEditView::setNoteWidget(QWidget * win) { - m_NoteWin = win; + CCNotePad* pv = dynamic_cast(win); + if (pv != nullptr) + { + m_NoteWin = pv; +} } sptr_t ScintillaHexEditView::execute(quint32 Msg, uptr_t wParam, sptr_t lParam) const { @@ -63,14 +68,34 @@ void ScintillaHexEditView::init() #endif setFont(font); setMarginsFont(font); - setMarginsBackgroundColor(StyleSet::marginsBackgroundColor); - - execute(SCI_SETTABWIDTH, 4); - setPaper(QColor(0xfc, 0xfc, 0xfc)); + + updateThemes(); + + connect(this->verticalScrollBar(), &QScrollBar::valueChanged, this, &ScintillaHexEditView::slot_scrollYValueChange); } +//Y方向滚动条值变化后的槽函数 +void ScintillaHexEditView::slot_scrollYValueChange(int value) +{ + if (value >= this->verticalScrollBar()->maximum()) + { + if (m_NoteWin != nullptr) + { + m_NoteWin->showChangePageTips(this); + } + } + else if (value == this->verticalScrollBar()->minimum()) + { + if (m_NoteWin != nullptr) + { + m_NoteWin->showChangePageTips(this); + } + } +} + + void ScintillaHexEditView::dragEnterEvent(QDragEnterEvent* event) { //if (event->mimeData()->hasFormat("text/uri-list")) //只能打开文本文件 @@ -96,3 +121,12 @@ void ScintillaHexEditView::dropEvent(QDropEvent* e) //qDebug() << ui.leftSrc->geometry() << ui.rightSrc->geometry() << QCursor::pos() << this->mapFromGlobal(QCursor::pos()); } + + +void ScintillaHexEditView::updateThemes() +{ + //如果是黑色主题,则单独做一些风格设置 + setColor(StyleSet::s_global_style->default_style.fgColor); + setMarginsBackgroundColor(StyleSet::s_global_style->line_number_margin.bgColor); + setPaper(StyleSet::s_global_style->default_style.bgColor); +} diff --git a/src/scintillahexeditview.h b/src/scintillahexeditview.h index baab3c6..fc824ca 100755 --- a/src/scintillahexeditview.h +++ b/src/scintillahexeditview.h @@ -8,6 +8,7 @@ typedef sptr_t(*SCINTILLA_FUNC) (sptr_t ptr, unsigned int, uptr_t, sptr_t); typedef sptr_t SCINTILLA_PTR; +class CCNotePad; class ScintillaHexEditView : public QsciScintilla { Q_OBJECT @@ -20,9 +21,14 @@ public: sptr_t execute(quint32 Msg, uptr_t wParam = 0, sptr_t lParam = 0) const; + void updateThemes(); + private: void init(); +private slots: + void slot_scrollYValueChange(int value); + protected: void dragEnterEvent(QDragEnterEvent * event); void dropEvent(QDropEvent * e); @@ -34,5 +40,5 @@ private: SCINTILLA_FUNC m_pScintillaFunc = nullptr; SCINTILLA_PTR m_pScintillaPtr = 0; - QWidget* m_NoteWin; + CCNotePad* m_NoteWin; }; diff --git a/src/styleset.cpp b/src/styleset.cpp index 10d32eb..55bedb7 100755 --- a/src/styleset.cpp +++ b/src/styleset.cpp @@ -4,6 +4,7 @@ #include #include #include +#include QColor StyleSet::foldfgColor(0xe9, 0xe9, 0xe9, 100); @@ -13,12 +14,56 @@ QColor StyleSet::bookmarkBkColor(0xececec); int StyleSet::m_curStyleId = 0; + +GLOBAL_STYLE_OPS* StyleSet::s_global_style = nullptr; + StyleSet::StyleSet() -{} +{ + init(); +} StyleSet::~StyleSet() {} +void StyleSet::init() +{ + if (s_global_style == nullptr) + { + s_global_style = new GLOBAL_STYLE_OPS(); + + s_global_style->default_style.styleId = 32; + s_global_style->indent_guideline.styleId = 37; + s_global_style->brace_highight.styleId = 34; + s_global_style->bad_brace_color.styleId = 35; + s_global_style->current_line_background_color.styleId = -1; + s_global_style->select_text_color.styleId = -1; + s_global_style->caret_colour.styleId = 2069; + s_global_style->edge_colour.styleId = -1; + s_global_style->line_number_margin.styleId = 33; + s_global_style->bookmark_margin.styleId = -1; + s_global_style->fold.styleId = -1; + s_global_style->fold_active.styleId = -1; + s_global_style->fold_margin.styleId = -1; + s_global_style->white_space_stybol.styleId = -1; + s_global_style->smart_highlighting.styleId = 29; + s_global_style->find_mark_style.styleId = 31; + s_global_style->mark_style_1.styleId = 25; + s_global_style->mark_style_2.styleId = 24; + s_global_style->mark_style_3.styleId = 23; + s_global_style->mark_style_4.styleId = 22; + s_global_style->mark_style_5.styleId = 21; + s_global_style->incremental_highlight.styleId = 28; + s_global_style->tags_match_highlight.styleId = 27; + s_global_style->tags_attribute.styleId = 26; + //s_global_style->active_tab_focused.styleId = -1; + //s_global_style->active_tab_unfocused.styleId = -1; + //s_global_style->active_tab_text.styleId = -1; + //s_global_style->inactive_tabs.styleId = -1; + s_global_style->url_hoverred.styleId = -1; + } + +} + void StyleSet::setCommonStyle(QColor foldfgColor_, QColor foldbgColor_, QColor marginsBackgroundColor_, QString colorName) { foldfgColor = foldfgColor_; @@ -47,48 +92,114 @@ void StyleSet::setCommonStyle(QColor foldfgColor_, QColor foldbgColor_, QColor m void StyleSet::setSkin(int id) { + m_curStyleId = id; + QsciLexer::setCurThemes(m_curStyleId); + StyleSet::init(); + loadGolbalStyle(); + switch (id) { case DEFAULT_SE: setDefaultStyle(); break; - case LIGHT_SE: - setLightStyle(); + case BESPIN: + case BLACK_BOARD: + case BLUE_LIGHT: + case CHOCO: + case DANSLE_RUSH_DARK: + case DEEP_BLACK: + case LAVENDER: + case HOT_FUDGE_SUNDAE: + case MISTY_ROSE: + case MONO_INDUSTRIAL: + case MONOKAI: + case OBSIDIAN: + case PLASTIC_CODE: + case RUBY_BLUE: + case TWILIGHT: + case VIBRANT_INK: + case YELLOW_RICE: + setCommonStyle(); break; - case THIN_BLUE_SE: - setThinBlueStyle(); - break; - case THIN_YELLOW_SE: - setThinYellowStyle(); - break; - case RICE_YELLOW_SE: - setRiceYellowStyle(); - break; - case SILVER_SE: - setSilverStyle(); - break; - case LAVENDER_SE: - setLavenderBlushStyle(); - break; - case MISTYROSE_SE: - setMistyRoseStyle(); - break; - case BLACK_SE: - setBlackStyle(); + case MAX_SE: break; default: - id = 0; - setDefaultStyle(); break; } +} - m_curStyleId = id; +void StyleSet::loadGolbalStyle() +{ + QsciLexer* pLexer = ScintillaEditView::createLexer(L_GLOBAL); + QsciLexerGlobal* pGlobalLexer = dynamic_cast(pLexer); + if (pGlobalLexer != nullptr) + { + //ȡɫȻ롣ScintillaEditViewֱЩOne_Stype_Infoֵ + One_Stype_Info* pAddr = &s_global_style->global_style; + + for (int i = 0; i <= URL_HOVERRED; ++i) + { + pAddr[i].fgColor = pGlobalLexer->color(i); + pAddr[i].bgColor = pGlobalLexer->paper(i); + pAddr[i].font = pGlobalLexer->font(i); + } + } + delete pLexer; } QString StyleSet::getCurrentStyle() { - static const QString style[MAX_SE] = {"default","ligth","thinblue","thinyellow","riceyellow","slive","lavender","mistyrose","black" }; - return style[m_curStyleId]; + return getStyleName(m_curStyleId); +} + +//Ƿɫϵ +bool StyleSet::isCurrentDeepStyle() +{ + switch (m_curStyleId) + { + case DEFAULT_SE: + case BLUE_LIGHT: + case YELLOW_RICE: + case MISTY_ROSE: + case LAVENDER: + return false; + + case BESPIN: + case BLACK_BOARD: + case CHOCO: + case DANSLE_RUSH_DARK: + case DEEP_BLACK: + case HOT_FUDGE_SUNDAE: + case MONO_INDUSTRIAL: + case MONOKAI: + case OBSIDIAN: + case PLASTIC_CODE: + case RUBY_BLUE: + case TWILIGHT: + case VIBRANT_INK: + return true; + + default: + break; + } + return false; +} + +QString StyleSet::getStyleName(int styleId) +{ + static const QString style[MAX_SE] = { "Default","Bespin","Black board","Blue light",\ + "Choco","DansLeRuSH-Dark",\ + "Deep Black","lavender","HotFudgeSundae","misty rose",\ + "Mono Industrial","Monokai","Obsidian","Plastic Code Wrap",\ + "Ruby Blue","Twilight","Vibrant Ink",\ + "yellow rice" }; + + return style[styleId]; +} + +void StyleSet::setCurrentStyle(int themes) +{ + setSkin(themes); } void StyleSet::setDefaultStyle() @@ -117,14 +228,14 @@ void StyleSet::setDefaultStyle() void StyleSet::setLightStyle() { - m_curStyleId = LIGHT_SE; + //m_curStyleId = LIGHT_SE; bookmarkBkColor = QColor(0xE0F3Fc); setCommonStyle(QColor(0xea, 0xf7, 0xff, 100), QColor(0xeaf7ff), QColor(0xe8f5fd), "#EAF7FF"); } void StyleSet::setThinBlueStyle() { - m_curStyleId = THIN_BLUE_SE; + //m_curStyleId = THIN_BLUE_SE; bookmarkBkColor = QColor(0xE3e0F0); setCommonStyle(QColor(0xd7, 0xe3, 0xf4, 100), QColor(0xd7e3f4), QColor(0xd5e1f1), "#D7E3F4"); } @@ -132,7 +243,7 @@ void StyleSet::setThinBlueStyle() //ֽ void StyleSet::setThinYellowStyle() { - m_curStyleId = THIN_YELLOW_SE; + //m_curStyleId = THIN_YELLOW_SE; bookmarkBkColor = QColor(0xF4F0E0); setCommonStyle(QColor(0xf9, 0xf0, 0xe1, 100), QColor(0xf9f0e1), QColor(0xf7f0e0), "#F9F0E1"); } @@ -140,7 +251,7 @@ void StyleSet::setThinYellowStyle() //ֽ void StyleSet::setRiceYellowStyle() { - m_curStyleId = RICE_YELLOW_SE; + //m_curStyleId = RICE_YELLOW_SE; bookmarkBkColor = QColor(0xF0F0E8); setCommonStyle(QColor(0xf6, 0xf3, 0xea, 100), QColor(0xf6f3ea), QColor(0xf4f1e9), "#F6F3EA"); } @@ -148,7 +259,7 @@ void StyleSet::setRiceYellowStyle() //ɫ void StyleSet::setSilverStyle() { - m_curStyleId = SILVER_SE; + //m_curStyleId = SILVER_SE; bookmarkBkColor = QColor(0xE4E4E4); setCommonStyle(QColor(0xe9, 0xe8, 0xe4, 100), QColor(0xe9e8e4), QColor(0xe7e6e2), "#E9E8E4"); } @@ -156,7 +267,7 @@ void StyleSet::setSilverStyle() //̸ɫ#FFF0F5 void StyleSet::setLavenderBlushStyle() { - m_curStyleId = LAVENDER_SE; + //m_curStyleId = LAVENDER_SE; bookmarkBkColor = QColor(0xFCF0F0); setCommonStyle(QColor(0xff, 0xf0, 0xf5, 100), QColor(0xFFF0F5), QColor(0xFdF0F3), "#FFF0F5"); } @@ -164,13 +275,14 @@ void StyleSet::setLavenderBlushStyle() //MistyRose void StyleSet::setMistyRoseStyle() { - m_curStyleId = MISTYROSE_SE; + //m_curStyleId = MISTYROSE_SE; bookmarkBkColor = QColor(0xFCE0E0); setCommonStyle(QColor(0xff, 0xe4, 0xe1, 100), QColor(0xFFE4E1), QColor(0xFdE2E0), "#FFE4E1"); } void StyleSet::setBlackStyle() { +#if 0 m_curStyleId = BLACK_SE; foldfgColor = QColor(0,0, 0); foldbgColor = QColor(32, 32, 40); @@ -198,4 +310,49 @@ void StyleSet::setBlackStyle() qApp->setStyleSheet(styleSheet); } file.close(); +#endif + + m_curStyleId = BLACK_SE; + + foldfgColor = QColor(0xe9, 0xe9, 0xe9, 100); + foldbgColor = QColor(0xff, 0xff, 0xff); + marginsBackgroundColor = QColor(57, 58, 60); + bookmarkBkColor = QColor(53, 54, 56); + + QFile file(":/qss/myblack.qss"); //qssļ·:/lightblue.qss + QString styleSheet; + if (file.open(QIODevice::Text | QIODevice::ReadOnly)) + { + styleSheet = file.readAll(); + QPalette palette; + palette.setColor(QPalette::Window, QColor(0xf0, 0xf0, 0xf0)); + palette.setColor(QPalette::Base, QColor(0xff, 0xff, 0xff)); + palette.setColor(QPalette::Button, QColor(0xf0, 0xf0, 0xf0)); + qApp->setPalette(palette); + qApp->setStyleSheet(styleSheet); + } + file.close(); } +void StyleSet::setCommonStyle() +{ + QFile file(":/qss/common.qss"); + QString styleSheet; + if (file.open(QIODevice::Text | QIODevice::ReadOnly)) + { + styleSheet = file.readAll(); + styleSheet.replace("#ffffff", s_global_style->default_style.fgColor.name()); + styleSheet.replace("#444444", s_global_style->default_style.bgColor.name()); + if (isCurrentDeepStyle()) + { + styleSheet.replace("#00CCFF", "#0000ff"); + } + + QPalette palette; + palette.setColor(QPalette::Window, QColor(0xf0, 0xf0, 0xf0)); + palette.setColor(QPalette::Base, QColor(0xff, 0xff, 0xff)); + palette.setColor(QPalette::Button, QColor(0xf0, 0xf0, 0xf0)); + qApp->setPalette(palette); + qApp->setStyleSheet(styleSheet); + } + file.close(); +} \ No newline at end of file diff --git a/src/styleset.h b/src/styleset.h index 39af083..223e956 100755 --- a/src/styleset.h +++ b/src/styleset.h @@ -1,19 +1,79 @@ #pragma once #include +#include enum StyleId { DEFAULT_SE=0, - LIGHT_SE, - THIN_BLUE_SE, - THIN_YELLOW_SE, - RICE_YELLOW_SE, - SILVER_SE, - LAVENDER_SE, - MISTYROSE_SE, - BLACK_SE, + BESPIN, + BLACK_BOARD, + BLUE_LIGHT, + CHOCO, + DANSLE_RUSH_DARK, + DEEP_BLACK, + LAVENDER, + HOT_FUDGE_SUNDAE, + MISTY_ROSE, + MONO_INDUSTRIAL, + MONOKAI, + OBSIDIAN, + PLASTIC_CODE, + RUBY_BLUE, + TWILIGHT, + VIBRANT_INK, + YELLOW_RICE, MAX_SE, }; +#define BLACK_SE DEEP_BLACK + +struct One_Stype_Info { + int styleId; + QColor fgColor; + QColor bgColor; + QFont font; //fontУ1壬СЩԣŴСû壬дСʹСʾ + One_Stype_Info() :styleId(-1) + { + } + One_Stype_Info(int id, QColor fg, QColor bg) :styleId(id), fgColor(fg), bgColor(bg) + { + } +}; + + +//ǰȫַԣеʽ޸ģ޸ṹ壬Ȼطٸ޸ĺĽṹ壬ͬ +struct GLOBAL_STYLE_OPS { + One_Stype_Info global_style; + One_Stype_Info default_style; + One_Stype_Info indent_guideline; + One_Stype_Info brace_highight; + One_Stype_Info bad_brace_color; + One_Stype_Info current_line_background_color; + One_Stype_Info select_text_color; + One_Stype_Info caret_colour; + One_Stype_Info edge_colour; + One_Stype_Info line_number_margin; + One_Stype_Info bookmark_margin; + One_Stype_Info fold; + One_Stype_Info fold_active; + One_Stype_Info fold_margin; + One_Stype_Info white_space_stybol; + One_Stype_Info smart_highlighting; + One_Stype_Info find_mark_style; + One_Stype_Info mark_style_1; + One_Stype_Info mark_style_2; + One_Stype_Info mark_style_3; + One_Stype_Info mark_style_4; + One_Stype_Info mark_style_5; + One_Stype_Info incremental_highlight; + One_Stype_Info tags_match_highlight; + One_Stype_Info tags_attribute; + //One_Stype_Info active_tab_focused; + //One_Stype_Info active_tab_unfocused; + //One_Stype_Info active_tab_text; + //One_Stype_Info inactive_tabs; + One_Stype_Info url_hoverred; +}; + class StyleSet { public: @@ -21,13 +81,18 @@ public: ~StyleSet(); static void setCommonStyle(QColor foldfgColor_, QColor foldbgColor_, QColor marginsBackgroundColor_, QString colorName); - + static void init(); + static void loadGolbalStyle(); static void setSkin(int id); + static void setCurrentStyle(int themes); static QString getCurrentStyle(); static StyleId getCurrentSytleId() { return StyleId(m_curStyleId); } + static bool isCurrentDeepStyle(); + + static QString getStyleName(int styleId); static QColor foldfgColor; static QColor foldbgColor; static QColor marginsBackgroundColor; @@ -43,4 +108,7 @@ public: static void setLavenderBlushStyle(); static void setMistyRoseStyle(); static void setBlackStyle(); + static void setCommonStyle(); + + static GLOBAL_STYLE_OPS* s_global_style; }; diff --git a/vs2017_sln/RealCompare.sln b/vs2017_sln/RealCompare.sln index 0b12021..119d403 100755 --- a/vs2017_sln/RealCompare.sln +++ b/vs2017_sln/RealCompare.sln @@ -3,29 +3,29 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.28307.1972 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qscintilla", "..\src\qscint\src\qscintilla.vcxproj", "{9BC42707-EE25-3B28-9906-F7919E273020}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RealCompare", "..\src\RealCompare.vcxproj", "{26BC87D0-189B-3661-B87D-347CF9E0A47F}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qscintilla", "..\src\qscint\src\qscintilla.vcxproj", "{9BC42707-EE25-3B28-9906-F7919E273020}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {9BC42707-EE25-3B28-9906-F7919E273020}.Debug|x64.ActiveCfg = Debug|x64 - {9BC42707-EE25-3B28-9906-F7919E273020}.Debug|x64.Build.0 = Debug|x64 - {9BC42707-EE25-3B28-9906-F7919E273020}.Release|x64.ActiveCfg = Release|x64 - {9BC42707-EE25-3B28-9906-F7919E273020}.Release|x64.Build.0 = Release|x64 {26BC87D0-189B-3661-B87D-347CF9E0A47F}.Debug|x64.ActiveCfg = Debug|x64 {26BC87D0-189B-3661-B87D-347CF9E0A47F}.Debug|x64.Build.0 = Debug|x64 {26BC87D0-189B-3661-B87D-347CF9E0A47F}.Release|x64.ActiveCfg = Release|x64 {26BC87D0-189B-3661-B87D-347CF9E0A47F}.Release|x64.Build.0 = Release|x64 + {9BC42707-EE25-3B28-9906-F7919E273020}.Debug|x64.ActiveCfg = Debug|x64 + {9BC42707-EE25-3B28-9906-F7919E273020}.Debug|x64.Build.0 = Debug|x64 + {9BC42707-EE25-3B28-9906-F7919E273020}.Release|x64.ActiveCfg = Release|x64 + {9BC42707-EE25-3B28-9906-F7919E273020}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {E8FE0D11-F49B-4EC0-9262-B44348F56F19} + SolutionGuid = {F8D03E96-542B-49CA-8FE2-21F7AF7CDD2E} EndGlobalSection EndGlobal