diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/COPYING b/COPYING old mode 100644 new mode 100755 index 818433ecc0e094a4db1023c68b33f24344643ad8..94a9ed024d3859793618152ea559a168bbcbb5e2 --- a/COPYING +++ b/COPYING @@ -1,674 +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 -. + 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/DSView/CMake/FindFFTW.cmake b/DSView/CMake/FindFFTW.cmake old mode 100644 new mode 100755 diff --git a/DSView/CMake/Findlibusb-1.0.cmake b/DSView/CMake/Findlibusb-1.0.cmake old mode 100644 new mode 100755 diff --git a/DSView/CMake/Findlibzip.cmake b/DSView/CMake/Findlibzip.cmake old mode 100644 new mode 100755 diff --git a/DSView/CMakeLists.txt b/DSView/CMakeLists.txt old mode 100644 new mode 100755 index c1c33e10f7eee360023fa16223952070c846f2ad..6e70b639f871bdedff3737b6c9f9c5029d9e2f3a --- a/DSView/CMakeLists.txt +++ b/DSView/CMakeLists.txt @@ -104,9 +104,9 @@ find_package(FFTW REQUIRED) set(DS_TITLE DSView) set(DS_DESCRIPTION "A GUI for instruments of DreamSourceLab") -set(DS_VERSION_MAJOR 0) -set(DS_VERSION_MINOR 9) -set(DS_VERSION_MICRO 9) +set(DS_VERSION_MAJOR 1) +set(DS_VERSION_MINOR 0) +set(DS_VERSION_MICRO 0) set(DS_VERSION_STRING ${DS_VERSION_MAJOR}.${DS_VERSION_MINOR}.${DS_VERSION_MICRO} ) @@ -121,95 +121,102 @@ configure_file ( #------------------------------------------------------------------------------- set(DSView_SOURCES - main.cpp - pv/sigsession.cpp - pv/mainwindow.cpp - pv/devicemanager.cpp - pv/data/snapshot.cpp - pv/data/signaldata.cpp - pv/data/logicsnapshot.cpp - pv/data/logic.cpp - pv/data/analogsnapshot.cpp - pv/data/analog.cpp - pv/dialogs/deviceoptions.cpp - pv/prop/property.cpp - pv/prop/int.cpp - pv/prop/enum.cpp - pv/prop/double.cpp - pv/prop/bool.cpp - pv/prop/binding/binding.cpp - pv/toolbars/samplingbar.cpp - pv/view/viewport.cpp - pv/view/view.cpp - pv/view/timemarker.cpp - pv/view/signal.cpp - pv/view/ruler.cpp - pv/view/logicsignal.cpp - pv/view/header.cpp - pv/view/cursor.cpp - pv/view/analogsignal.cpp - pv/prop/binding/deviceoptions.cpp - pv/toolbars/trigbar.cpp - pv/toolbars/filebar.cpp - pv/dock/protocoldock.cpp - pv/dock/triggerdock.cpp - pv/dock/measuredock.cpp - pv/dock/searchdock.cpp - pv/toolbars/logobar.cpp - pv/data/groupsnapshot.cpp - pv/view/groupsignal.cpp - pv/data/group.cpp - pv/dialogs/about.cpp - pv/dialogs/search.cpp - pv/data/dsosnapshot.cpp + main.cpp + pv/sigsession.cpp + pv/mainwindow.cpp + pv/devicemanager.cpp + pv/data/snapshot.cpp + pv/data/signaldata.cpp + pv/data/logicsnapshot.cpp + pv/data/logic.cpp + pv/data/analogsnapshot.cpp + pv/data/analog.cpp + pv/dialogs/deviceoptions.cpp + pv/prop/property.cpp + pv/prop/int.cpp + pv/prop/enum.cpp + pv/prop/double.cpp + pv/prop/bool.cpp + pv/prop/binding/binding.cpp + pv/toolbars/samplingbar.cpp + pv/view/viewport.cpp + pv/view/view.cpp + pv/view/timemarker.cpp + pv/view/signal.cpp + pv/view/ruler.cpp + pv/view/logicsignal.cpp + pv/view/header.cpp + pv/view/cursor.cpp + pv/view/analogsignal.cpp + pv/prop/binding/deviceoptions.cpp + pv/toolbars/trigbar.cpp + pv/toolbars/filebar.cpp + pv/dock/protocoldock.cpp + pv/dock/triggerdock.cpp + pv/dock/measuredock.cpp + pv/dock/searchdock.cpp + pv/toolbars/logobar.cpp + pv/data/groupsnapshot.cpp + pv/view/groupsignal.cpp + pv/data/group.cpp + pv/dialogs/about.cpp + pv/dialogs/search.cpp + pv/data/dsosnapshot.cpp pv/data/dso.cpp - pv/view/dsosignal.cpp - pv/view/dsldial.cpp - pv/dock/dsotriggerdock.cpp - pv/view/trace.cpp - pv/view/selectableitem.cpp - pv/data/decoderstack.cpp - pv/data/decode/rowdata.cpp - pv/data/decode/row.cpp - pv/data/decode/decoder.cpp - pv/data/decode/annotation.cpp - pv/view/decodetrace.cpp - pv/prop/binding/decoderoptions.cpp - pv/widgets/fakelineedit.cpp - pv/widgets/decodermenu.cpp - pv/widgets/decodergroupbox.cpp - pv/prop/string.cpp - pv/device/sessionfile.cpp - pv/device/inputfile.cpp - pv/device/file.cpp - pv/device/devinst.cpp - pv/dialogs/storeprogress.cpp - pv/storesession.cpp - pv/view/devmode.cpp - pv/device/device.cpp - pv/dialogs/waitingdialog.cpp - pv/dialogs/dsomeasure.cpp - pv/dialogs/calibration.cpp - pv/data/decodermodel.cpp - pv/dialogs/protocollist.cpp - pv/dialogs/protocolexp.cpp - pv/dialogs/fftoptions.cpp - pv/data/mathstack.cpp - pv/view/mathtrace.cpp - dsapplication.cpp - pv/widgets/viewstatus.cpp - pv/toolbars/titlebar.cpp - pv/mainframe.cpp - pv/widgets/border.cpp - pv/dialogs/dsmessagebox.cpp - pv/dialogs/shadow.cpp + pv/view/dsosignal.cpp + pv/view/dsldial.cpp + pv/dock/dsotriggerdock.cpp + pv/view/trace.cpp + pv/view/selectableitem.cpp + pv/data/decoderstack.cpp + pv/data/decode/rowdata.cpp + pv/data/decode/row.cpp + pv/data/decode/decoder.cpp + pv/data/decode/annotation.cpp + pv/view/decodetrace.cpp + pv/prop/binding/decoderoptions.cpp + pv/widgets/fakelineedit.cpp + pv/widgets/decodermenu.cpp + pv/widgets/decodergroupbox.cpp + pv/prop/string.cpp + pv/device/sessionfile.cpp + pv/device/inputfile.cpp + pv/device/file.cpp + pv/device/devinst.cpp + pv/dialogs/storeprogress.cpp + pv/storesession.cpp + pv/view/devmode.cpp + pv/device/device.cpp + pv/dialogs/waitingdialog.cpp + pv/dialogs/dsomeasure.cpp + pv/dialogs/calibration.cpp + pv/data/decodermodel.cpp + pv/dialogs/protocollist.cpp + pv/dialogs/protocolexp.cpp + pv/dialogs/fftoptions.cpp + pv/data/mathstack.cpp + pv/view/mathtrace.cpp + dsapplication.cpp + pv/toolbars/titlebar.cpp + pv/mainframe.cpp + pv/widgets/border.cpp + pv/dialogs/dsmessagebox.cpp + pv/dialogs/shadow.cpp pv/dialogs/dsdialog.cpp pv/dialogs/interval.cpp pv/prop/binding/probeoptions.cpp + pv/view/viewstatus.cpp + pv/dialogs/lissajousoptions.cpp + pv/view/lissajoustrace.cpp + pv/view/spectrumtrace.cpp + pv/data/spectrumstack.cpp + pv/dialogs/mathoptions.cpp + pv/dialogs/regionoptions.cpp + pv/view/xcursor.cpp ) set(DSView_HEADERS - pv/sigsession.h + pv/sigsession.h pv/mainwindow.h pv/dialogs/deviceoptions.h pv/prop/property.h @@ -254,7 +261,7 @@ set(DSView_HEADERS pv/dialogs/fftoptions.h pv/data/mathstack.h pv/view/mathtrace.h - pv/widgets/viewstatus.h + pv/view/viewstatus.h pv/toolbars/titlebar.h pv/mainframe.h pv/widgets/border.h @@ -262,6 +269,17 @@ set(DSView_HEADERS pv/dialogs/shadow.h pv/dialogs/dsdialog.h pv/dialogs/interval.h + pv/dialogs/lissajousoptions.h + pv/view/lissajoustrace.h + pv/view/spectrumtrace.h + pv/data/spectrumstack.h + pv/dialogs/mathoptions.h + pv/dialogs/regionoptions.h + pv/view/xcursor.h + pv/view/signal.h + pv/view/logicsignal.h + pv/view/analogsignal.h + pv/view/dsosignal.h ) set(DSView_FORMS @@ -269,7 +287,8 @@ set(DSView_FORMS set(DSView_RESOURCES DSView.qrc - darkstyle/style.qrc + themes/breeze.qrc + languages/language.qrc ) if(ENABLE_DECODE) @@ -401,8 +420,10 @@ set_target_properties(${PROJECT_NAME} PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_ install(TARGETS ${PROJECT_NAME} DESTINATION bin/) install(DIRECTORY res DESTINATION share/${PROJECT_NAME}) install(FILES icons/logo.png DESTINATION share/${PROJECT_NAME} RENAME logo.png) -install(FILES ../NEWS DESTINATION share/${PROJECT_NAME} RENAME NEWS) -install(FILES ../ug.pdf DESTINATION share/${PROJECT_NAME} RENAME ug.pdf) +install(FILES ../NEWS25 DESTINATION share/${PROJECT_NAME} RENAME NEWS25) +install(FILES ../NEWS31 DESTINATION share/${PROJECT_NAME} RENAME NEWS31) +install(FILES ../ug25.pdf DESTINATION share/${PROJECT_NAME} RENAME ug25.pdf) +install(FILES ../ug31.pdf DESTINATION share/${PROJECT_NAME} RENAME ug31.pdf) install(FILES DreamSourceLab.rules DESTINATION /etc/udev/rules.d/) install(FILES DSView.desktop DESTINATION /usr/share/applications/) diff --git a/DSView/COPYING b/DSView/COPYING old mode 100644 new mode 100755 diff --git a/DSView/DSView.desktop b/DSView/DSView.desktop old mode 100644 new mode 100755 diff --git a/DSView/DSView.qrc b/DSView/DSView.qrc old mode 100644 new mode 100755 index 54259634e0b2510cc6fbd557ad894db2c1f74751..a50ef6b97ebb35dee2b2293c855aebdb929e1415 --- a/DSView/DSView.qrc +++ b/DSView/DSView.qrc @@ -1,71 +1,137 @@ - icons/search.png - icons/next.png - icons/pre.png - icons/file.png - icons/save.png - icons/open.png - icons/params.png - stylesheet.qss - icons/down-arrow.png - icons/slider-handle.png - icons/trigger.png - icons/measure.png - icons/search-bar.png - icons/protocol.png - icons/logo_noColor.png - icons/logo_color.png - icons/capture.png - icons/stop.png - icons/start.png - icons/dsl_logo.png - icons/logo.png - icons/hidden.png - icons/shown.png - icons/instant.png - icons/trigger_dis.png - icons/file_dis.png - icons/measure_dis.png - icons/protocol_dis.png - icons/search-bar_dis.png - icons/params_dis.png - icons/gear.png - icons/wait.gif - icons/instant_dis.png - icons/start_dis.png - icons/settings.png - darkstyle/style.qss - icons/export.png - icons/single.png - icons/single_dis.png - icons/math.png - icons/math_dis.png - icons/fft.png icons/Blackman.png + icons/dsl_logo.png icons/Flat_top.png icons/Hamming.png icons/Hann.png + icons/logo.png icons/Rectangle.png - icons/close.png - icons/maximize.png - icons/minimize.png - icons/restore.png - icons/nav.png - icons/oneloop.png - icons/repeat.png - icons/moder.png - icons/moder_dis.png - icons/modes.png - icons/modes_dis.png - icons/add.png - icons/del.png - icons/add_dis.png - icons/del_dis.png - icons/about.png - icons/manual.png - icons/bug.png - icons/support.png - icons/showDoc.png + icons/search.png + icons/dark/about.png + icons/dark/add.png + icons/dark/bug.png + icons/dark/capture.png + icons/dark/close.png + icons/dark/dark.png + icons/dark/del.png + icons/dark/display.png + icons/dark/down-arrow.png + icons/dark/export.png + icons/dark/fft.png + icons/dark/file.png + icons/dark/gear.png + icons/dark/hidden.png + icons/dark/instant.png + icons/dark/light.png + icons/dark/logo_color.png + icons/dark/logo_noColor.png + icons/dark/manual.png + icons/dark/maximize.png + icons/dark/measure.png + icons/dark/minimize.png + icons/dark/moder.png + icons/dark/modes.png + icons/dark/nav.png + icons/dark/next.png + icons/dark/oneloop.png + icons/dark/open.png + icons/dark/params.png + icons/dark/pre.png + icons/dark/protocol.png + icons/dark/repeat.png + icons/dark/restore.png + icons/dark/save.png + icons/dark/search.png + icons/dark/search-bar.png + icons/dark/shown.png + icons/dark/single.png + icons/dark/start.png + icons/dark/stop.png + icons/dark/support.png + icons/dark/trigger.png + icons/light/about.png + icons/light/add.png + icons/light/bug.png + icons/light/capture.png + icons/light/close.png + icons/light/dark.png + icons/light/del.png + icons/light/display.png + icons/light/down-arrow.png + icons/light/export.png + icons/light/fft.png + icons/light/file.png + icons/light/gear.png + icons/light/hidden.png + icons/light/instant.png + icons/light/light.png + icons/light/logo_color.png + icons/light/logo_noColor.png + icons/light/manual.png + icons/light/maximize.png + icons/light/measure.png + icons/light/minimize.png + icons/light/moder.png + icons/light/modes.png + icons/light/nav.png + icons/light/next.png + icons/light/oneloop.png + icons/light/open.png + icons/light/params.png + icons/light/pre.png + icons/light/protocol.png + icons/light/repeat.png + icons/light/restore.png + icons/light/save.png + icons/light/search.png + icons/light/search-bar.png + icons/light/shown.png + icons/light/single.png + icons/light/start.png + icons/light/stop.png + icons/light/support.png + icons/light/trigger.png + icons/mAmplitude.png + icons/mBurst.png + icons/mDelay.png + icons/mFall.png + icons/mFreq.png + icons/mHigh.png + icons/mLow.png + icons/mMax.png + icons/mMean.png + icons/mMin.png + icons/mNduty.png + icons/mNover.png + icons/mNwidth.png + icons/mPcount.png + icons/mPduty.png + icons/mPeriod.png + icons/mPover.png + icons/mPwidth.png + icons/mRise.png + icons/mRms.png + icons/mVpp.png + icons/light/lissajous.png + icons/dark/lissajous.png + icons/light/function.png + icons/dark/function.png + icons/light/math.png + icons/dark/math.png + icons/math.png + icons/Chinese.png + icons/English.png + icons/lissajous.png + icons/light/wait.gif + icons/dark/wait.gif + icons/light/daq.png + icons/light/la.png + icons/light/osc.png + icons/dark/daq.png + icons/dark/la.png + icons/dark/osc.png + icons/showDoc25.png + icons/showDoc31.png diff --git a/DSView/DreamSourceLab.rules b/DSView/DreamSourceLab.rules old mode 100644 new mode 100755 diff --git a/DSView/INSTALL b/DSView/INSTALL old mode 100644 new mode 100755 index 9b20e3a5344aed9e0a57998cea2389ae323007eb..bb41a599aa1323c23752689a7e9c15b811616095 --- a/DSView/INSTALL +++ b/DSView/INSTALL @@ -1,49 +1,49 @@ -------------------------------------------------------------------------------- -INSTALL -------------------------------------------------------------------------------- - -Requirements ------------- - - - git - - g++ - - make - - libtool - - pkg-config >= 0.22 - - cmake >= 2.6 - - libglib >= 2.28.0 - - Qt >= 4.5 - - libboost >= 1.42 (including the following libs): - - libboost-system - - libboost-thread - - libsigrok4DSL >= 0.2.0 - - -Building and installing ------------------------ -Get the DSView source code from: www.dreamsourcelab.com/download.html -In order to build it, run: - - $ cd DSView - $ cmake . - $ make - -For installing PulseView: - - $ make install - -See the following wiki page for more (OS-specific) instructions: - - http://sigrok.org/wiki/Building - - -Creating a source distribution package --------------------------------------- - -In order to build a source package begin with an unconfigured source tree. - - $ mkdir dist - $ cd dist - $ cmake .. - $ make package_source - +------------------------------------------------------------------------------- +INSTALL +------------------------------------------------------------------------------- + +Requirements +------------ + + - git + - g++ + - make + - libtool + - pkg-config >= 0.22 + - cmake >= 2.6 + - libglib >= 2.28.0 + - Qt >= 4.5 + - libboost >= 1.42 (including the following libs): + - libboost-system + - libboost-thread + - libsigrok4DSL >= 0.2.0 + + +Building and installing +----------------------- +Get the DSView source code from: www.dreamsourcelab.com/download.html +In order to build it, run: + + $ cd DSView + $ cmake . + $ make + +For installing PulseView: + + $ make install + +See the following wiki page for more (OS-specific) instructions: + + http://sigrok.org/wiki/Building + + +Creating a source distribution package +-------------------------------------- + +In order to build a source package begin with an unconfigured source tree. + + $ mkdir dist + $ cd dist + $ cmake .. + $ make package_source + diff --git a/DSView/NEWS b/DSView/NEWS old mode 100644 new mode 100755 index e7c2c79cc62872ac7beff8ce48ddf8cfa67266a1..dbbe97099c9ce15b360a29c8761b04fb7ecf0b98 --- a/DSView/NEWS +++ b/DSView/NEWS @@ -1,5 +1,5 @@ -0.1.0 (2013-12-15) ------------------- - - * Initial release. - +0.1.0 (2013-12-15) +------------------ + + * Initial release. + diff --git a/DSView/README b/DSView/README old mode 100644 new mode 100755 diff --git a/DSView/config.h.in b/DSView/config.h.in old mode 100644 new mode 100755 diff --git a/DSView/darkstyle/rc/branch_closed-on.png b/DSView/darkstyle/rc/branch_closed-on.png deleted file mode 100755 index d081e9b3b90d774450a8ea48f1184019e33a755a..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/branch_closed-on.png and /dev/null differ diff --git a/DSView/darkstyle/rc/branch_closed.png b/DSView/darkstyle/rc/branch_closed.png deleted file mode 100755 index d652159a365396a046329cfc7695c89ee54431ca..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/branch_closed.png and /dev/null differ diff --git a/DSView/darkstyle/rc/branch_open-on.png b/DSView/darkstyle/rc/branch_open-on.png deleted file mode 100755 index ec372b27d1adc1268321a1ffaa9a884daf6de7e6..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/branch_open-on.png and /dev/null differ diff --git a/DSView/darkstyle/rc/branch_open.png b/DSView/darkstyle/rc/branch_open.png deleted file mode 100755 index 66f8e1ac619d242f3d5a31ffb11291c09ea40468..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/branch_open.png and /dev/null differ diff --git a/DSView/darkstyle/rc/checkbox_checked.png b/DSView/darkstyle/rc/checkbox_checked.png deleted file mode 100755 index 830cfee6568b718535c61564b95caf2d17c0958a..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/checkbox_checked.png and /dev/null differ diff --git a/DSView/darkstyle/rc/checkbox_checked_disabled.png b/DSView/darkstyle/rc/checkbox_checked_disabled.png deleted file mode 100755 index cb63cc2fac47ad304451f864be5fb9b9085910ee..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/checkbox_checked_disabled.png and /dev/null differ diff --git a/DSView/darkstyle/rc/checkbox_checked_focus.png b/DSView/darkstyle/rc/checkbox_checked_focus.png deleted file mode 100755 index 3cf0e54059775600a8e836deedb6554ad585602d..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/checkbox_checked_focus.png and /dev/null differ diff --git a/DSView/darkstyle/rc/checkbox_indeterminate.png b/DSView/darkstyle/rc/checkbox_indeterminate.png deleted file mode 100755 index 41024f7688c0623c853ee9ceb8138949cb167738..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/checkbox_indeterminate.png and /dev/null differ diff --git a/DSView/darkstyle/rc/checkbox_indeterminate_disabled.png b/DSView/darkstyle/rc/checkbox_indeterminate_disabled.png deleted file mode 100755 index abdc01d906626d5954b7eaa611fabcce80653251..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/checkbox_indeterminate_disabled.png and /dev/null differ diff --git a/DSView/darkstyle/rc/checkbox_indeterminate_focus.png b/DSView/darkstyle/rc/checkbox_indeterminate_focus.png deleted file mode 100755 index a9a16f7e0616b4da40c0f19775dd02bcf28ce948..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/checkbox_indeterminate_focus.png and /dev/null differ diff --git a/DSView/darkstyle/rc/checkbox_unchecked.png b/DSView/darkstyle/rc/checkbox_unchecked.png deleted file mode 100755 index 2159aca9a10f75729912579b33a1226e575799aa..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/checkbox_unchecked.png and /dev/null differ diff --git a/DSView/darkstyle/rc/checkbox_unchecked_disabled.png b/DSView/darkstyle/rc/checkbox_unchecked_disabled.png deleted file mode 100755 index ade721e81ba47fa792d4586516b8744f8c49c8bb..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/checkbox_unchecked_disabled.png and /dev/null differ diff --git a/DSView/darkstyle/rc/checkbox_unchecked_focus.png b/DSView/darkstyle/rc/checkbox_unchecked_focus.png deleted file mode 100755 index 66f5bf5644e361728813470be3910ead5471f67f..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/checkbox_unchecked_focus.png and /dev/null differ diff --git a/DSView/darkstyle/rc/close-hover.png b/DSView/darkstyle/rc/close-hover.png deleted file mode 100755 index 657943a668b734138256aa7bb178661030fd4a1f..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/close-hover.png and /dev/null differ diff --git a/DSView/darkstyle/rc/close-pressed.png b/DSView/darkstyle/rc/close-pressed.png deleted file mode 100755 index 937d0059839ba44ac5cf03f8c047ee05815954d9..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/close-pressed.png and /dev/null differ diff --git a/DSView/darkstyle/rc/close.png b/DSView/darkstyle/rc/close.png deleted file mode 100755 index bc0f5761096ef24b8b4461d9252b42dad48d0d45..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/close.png and /dev/null differ diff --git a/DSView/darkstyle/rc/down_arrow.png b/DSView/darkstyle/rc/down_arrow.png deleted file mode 100755 index e271f7f90b4132c9d740058d8b6c915dbdd626d2..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/down_arrow.png and /dev/null differ diff --git a/DSView/darkstyle/rc/down_arrow_disabled.png b/DSView/darkstyle/rc/down_arrow_disabled.png deleted file mode 100755 index 5805d9842bb3c8bdf9ae741ebabc690a4929585a..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/down_arrow_disabled.png and /dev/null differ diff --git a/DSView/darkstyle/rc/left_arrow.png b/DSView/darkstyle/rc/left_arrow.png deleted file mode 100755 index f808d2d7208ea2fe99f6bf25bc2302fc4f36c00b..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/left_arrow.png and /dev/null differ diff --git a/DSView/darkstyle/rc/left_arrow_disabled.png b/DSView/darkstyle/rc/left_arrow_disabled.png deleted file mode 100755 index f5b9af8a34edb5f8dd767bf6afa303b89a31d38f..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/left_arrow_disabled.png and /dev/null differ diff --git a/DSView/darkstyle/rc/radio_checked.png b/DSView/darkstyle/rc/radio_checked.png deleted file mode 100755 index 235e6b0ba7849fa48efdd88799c29b703cac25a8..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/radio_checked.png and /dev/null differ diff --git a/DSView/darkstyle/rc/radio_checked_disabled.png b/DSView/darkstyle/rc/radio_checked_disabled.png deleted file mode 100755 index bf0051ede5f00d8cecf17b37c6bb9de38bb24e19..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/radio_checked_disabled.png and /dev/null differ diff --git a/DSView/darkstyle/rc/radio_checked_focus.png b/DSView/darkstyle/rc/radio_checked_focus.png deleted file mode 100755 index 14b1cb1c73089fdcbb45abe1a20425adb2dc229a..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/radio_checked_focus.png and /dev/null differ diff --git a/DSView/darkstyle/rc/radio_unchecked.png b/DSView/darkstyle/rc/radio_unchecked.png deleted file mode 100755 index 9a4def65c64a9d55441f82fe66fc7f46e5b73a75..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/radio_unchecked.png and /dev/null differ diff --git a/DSView/darkstyle/rc/radio_unchecked_disabled.png b/DSView/darkstyle/rc/radio_unchecked_disabled.png deleted file mode 100755 index 6ece890e750b0685bbd818f22e5fbf999ccd35e1..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/radio_unchecked_disabled.png and /dev/null differ diff --git a/DSView/darkstyle/rc/radio_unchecked_focus.png b/DSView/darkstyle/rc/radio_unchecked_focus.png deleted file mode 100755 index 27af8112b4ef7fb383e10da7ff20cdc02d1119e5..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/radio_unchecked_focus.png and /dev/null differ diff --git a/DSView/darkstyle/rc/right_arrow.png b/DSView/darkstyle/rc/right_arrow.png deleted file mode 100755 index 9b0a4e6a7a8097818d9c0626c84f19f4d690dd31..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/right_arrow.png and /dev/null differ diff --git a/DSView/darkstyle/rc/right_arrow_disabled.png b/DSView/darkstyle/rc/right_arrow_disabled.png deleted file mode 100755 index 5c0bee402ff962fe285183b321feba59dac4f3d6..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/right_arrow_disabled.png and /dev/null differ diff --git a/DSView/darkstyle/rc/sizegrip.png b/DSView/darkstyle/rc/sizegrip.png deleted file mode 100755 index 350583aaac4aa474ac449eaea2cc7ddd060276b9..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/sizegrip.png and /dev/null differ diff --git a/DSView/darkstyle/rc/stylesheet-branch-end.png b/DSView/darkstyle/rc/stylesheet-branch-end.png deleted file mode 100755 index cb5d3b51f8cf7fd0f0ed26cfea722fa5a632dc1a..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/stylesheet-branch-end.png and /dev/null differ diff --git a/DSView/darkstyle/rc/stylesheet-branch-more.png b/DSView/darkstyle/rc/stylesheet-branch-more.png deleted file mode 100755 index 62711409d7ed69ec98979394795822630458d9eb..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/stylesheet-branch-more.png and /dev/null differ diff --git a/DSView/darkstyle/rc/stylesheet-vline.png b/DSView/darkstyle/rc/stylesheet-vline.png deleted file mode 100755 index 87536cce16aabb3710663f720f8d354b1bb0b757..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/stylesheet-vline.png and /dev/null differ diff --git a/DSView/darkstyle/rc/transparent.png b/DSView/darkstyle/rc/transparent.png deleted file mode 100755 index 483df25137d1f267b9793bb6068bb58e8825f11f..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/transparent.png and /dev/null differ diff --git a/DSView/darkstyle/rc/undock.png b/DSView/darkstyle/rc/undock.png deleted file mode 100755 index 88691d779507c9b809391396407f5cb4a6497c40..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/undock.png and /dev/null differ diff --git a/DSView/darkstyle/rc/up_arrow.png b/DSView/darkstyle/rc/up_arrow.png deleted file mode 100755 index abcc7245212f19a5dbff1bb19647b1dd4bb05b6a..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/up_arrow.png and /dev/null differ diff --git a/DSView/darkstyle/rc/up_arrow_disabled.png b/DSView/darkstyle/rc/up_arrow_disabled.png deleted file mode 100755 index b9c8e3b53519f086536accd2e8adb193b66817d8..0000000000000000000000000000000000000000 Binary files a/DSView/darkstyle/rc/up_arrow_disabled.png and /dev/null differ diff --git a/DSView/darkstyle/style.qrc b/DSView/darkstyle/style.qrc deleted file mode 100755 index 055e402fedb09b1a69b111059621aa04c24b0347..0000000000000000000000000000000000000000 --- a/DSView/darkstyle/style.qrc +++ /dev/null @@ -1,42 +0,0 @@ - - - rc/up_arrow_disabled.png - rc/stylesheet-branch-end.png - rc/branch_closed-on.png - rc/stylesheet-vline.png - rc/branch_closed.png - rc/branch_open-on.png - rc/transparent.png - rc/right_arrow_disabled.png - rc/sizegrip.png - rc/close.png - rc/close-hover.png - rc/close-pressed.png - rc/down_arrow.png - rc/left_arrow.png - rc/stylesheet-branch-more.png - rc/up_arrow.png - rc/right_arrow.png - rc/left_arrow_disabled.png - rc/branch_open.png - rc/down_arrow_disabled.png - rc/undock.png - rc/checkbox_checked_disabled.png - rc/checkbox_checked_focus.png - rc/checkbox_checked.png - rc/checkbox_indeterminate.png - rc/checkbox_indeterminate_focus.png - rc/checkbox_unchecked_disabled.png - rc/checkbox_unchecked_focus.png - rc/checkbox_unchecked.png - rc/radio_checked_disabled.png - rc/radio_checked_focus.png - rc/radio_checked.png - rc/radio_unchecked_disabled.png - rc/radio_unchecked_focus.png - rc/radio_unchecked.png - - - style.qss - - diff --git a/DSView/darkstyle/style.qss b/DSView/darkstyle/style.qss deleted file mode 100755 index 28636f46c645c2eb4f50b6f3fdf0122183cf5fbe..0000000000000000000000000000000000000000 --- a/DSView/darkstyle/style.qss +++ /dev/null @@ -1,1302 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) <2013-2014> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -QProgressBar:horizontal { - border: 1px solid #3A3939; - text-align: center; - padding: 1px; - background: #201F1F; -} -QProgressBar::chunk:horizontal { - background-color: qlineargradient(spread:reflect, x1:1, y1:0.545, x2:1, y2:0, stop:0 rgba(28, 66, 111, 255), stop:1 rgba(37, 87, 146, 255)); -} - -QToolTip -{ - border: 1px solid #3A3939; - background-color: rgb(90, 102, 117);; - color: white; - padding: 1px; - opacity: 200; -} - -QWidget -{ - color: silver; - background-color: #302F2F; - selection-background-color:#3d8ec9; - selection-color: black; - background-clip: border; - border-image: none; - outline: 0; -} - -QWidget:item:hover -{ - background-color: #78879b; - color: black; -} - -QWidget:item:selected -{ - background-color: #3d8ec9; -} - -QCheckBox -{ - spacing: 0px; - outline: none; - color: #bbb; - margin-bottom: 2px; -} - -QCheckBox:disabled -{ - color: #777777; -} -QCheckBox::indicator, -QGroupBox::indicator -{ - width: 18px; - height: 18px; -} -QGroupBox::indicator -{ - margin-left: 2px; -} - -QCheckBox::indicator:unchecked, -QCheckBox::indicator:unchecked:hover, -QGroupBox::indicator:unchecked, -QGroupBox::indicator:unchecked:hover -{ - image: url(:/qss_icons/rc/checkbox_unchecked.png); -} - -QCheckBox::indicator:unchecked:focus, -QCheckBox::indicator:unchecked:pressed, -QGroupBox::indicator:unchecked:focus, -QGroupBox::indicator:unchecked:pressed -{ - border: none; - image: url(:/qss_icons/rc/checkbox_unchecked_focus.png); -} - -QCheckBox::indicator:checked, -QCheckBox::indicator:checked:hover, -QGroupBox::indicator:checked, -QGroupBox::indicator:checked:hover -{ - image: url(:/qss_icons/rc/checkbox_checked.png); -} - -QCheckBox::indicator:checked:focus, -QCheckBox::indicator:checked:pressed, -QGroupBox::indicator:checked:focus, -QGroupBox::indicator:checked:pressed -{ - border: none; - image: url(:/qss_icons/rc/checkbox_checked_focus.png); -} - -QCheckBox::indicator:indeterminate, -QCheckBox::indicator:indeterminate:hover, -QCheckBox::indicator:indeterminate:pressed -QGroupBox::indicator:indeterminate, -QGroupBox::indicator:indeterminate:hover, -QGroupBox::indicator:indeterminate:pressed -{ - image: url(:/qss_icons/rc/checkbox_indeterminate.png); -} - -QCheckBox::indicator:indeterminate:focus, -QGroupBox::indicator:indeterminate:focus -{ - image: url(:/qss_icons/rc/checkbox_indeterminate_focus.png); -} - -QCheckBox::indicator:checked:disabled, -QGroupBox::indicator:checked:disabled -{ - image: url(:/qss_icons/rc/checkbox_checked_disabled.png); -} - -QCheckBox::indicator:unchecked:disabled, -QGroupBox::indicator:unchecked:disabled -{ - image: url(:/qss_icons/rc/checkbox_unchecked_disabled.png); -} - -QRadioButton -{ - spacing: 5px; - outline: none; - color: #bbb; - margin-bottom: 2px; -} - -QRadioButton:disabled -{ - color: #777777; -} -QRadioButton::indicator -{ - width: 21px; - height: 21px; -} - -QRadioButton::indicator:unchecked, -QRadioButton::indicator:unchecked:hover -{ - image: url(:/qss_icons/rc/radio_unchecked.png); -} - -QRadioButton::indicator:unchecked:focus, -QRadioButton::indicator:unchecked:pressed -{ - border: none; - outline: none; - image: url(:/qss_icons/rc/radio_unchecked_focus.png); -} - -QRadioButton::indicator:checked, -QRadioButton::indicator:checked:hover -{ - border: none; - outline: none; - image: url(:/qss_icons/rc/radio_checked.png); -} - -QRadioButton::indicator:checked:focus, -QRadioButton::indicato::menu-arrowr:checked:pressed -{ - border: none; - outline: none; - image: url(:/qss_icons/rc/radio_checked_focus.png); -} - -QRadioButton::indicator:indeterminate, -QRadioButton::indicator:indeterminate:hover, -QRadioButton::indicator:indeterminate:pressed -{ - image: url(:/qss_icons/rc/radio_indeterminate.png); -} - -QRadioButton::indicator:checked:disabled -{ - outline: none; - image: url(:/qss_icons/rc/radio_checked_disabled.png); -} - -QRadioButton::indicator:unchecked:disabled -{ - image: url(:/qss_icons/rc/radio_unchecked_disabled.png); -} - - -QMenuBar -{ - background-color: #302F2F; - color: silver; -} - -QMenuBar::item -{ - background: transparent; -} - -QMenuBar::item:selected -{ - background: transparent; - border: 1px solid #3A3939; -} - -QMenuBar::item:pressed -{ - border: 1px solid #3A3939; - background-color: #3d8ec9; - color: black; - margin-bottom:-1px; - padding-bottom:1px; -} - -QMenu -{ - border: 1px solid #3A3939; - color: silver; - margin: 0px; -} - -QMenu::item -{ - padding: 5px 30px 5px 30px; - margin-left: 2px; - border: 1px solid transparent; /* reserve space for selection border */ -} - -QMenu::item:selected -{ - color: black; -} - -QMenu::separator { - height: 2px; - background: lightblue; - margin-left: 10px; - margin-right: 5px; -} - -QMenu::indicator { - width: 18px; - height: 18px; -} - -/* non-exclusive indicator = check box style indicator - (see QActionGroup::setExclusive) */ -QMenu::indicator:non-exclusive:unchecked { - image: url(:/qss_icons/rc/checkbox_unchecked.png); -} - -QMenu::indicator:non-exclusive:unchecked:selected { - image: url(:/qss_icons/rc/checkbox_unchecked_disabled.png); -} - -QMenu::indicator:non-exclusive:checked { - image: url(:/qss_icons/rc/checkbox_checked.png); -} - -QMenu::indicator:non-exclusive:checked:selected { - image: url(:/qss_icons/rc/checkbox_checked_disabled.png); -} - -/* exclusive indicator = radio button style indicator (see QActionGroup::setExclusive) */ -QMenu::indicator:exclusive:unchecked { - image: url(:/qss_icons/rc/radio_unchecked.png); -} - -QMenu::indicator:exclusive:unchecked:selected { - image: url(:/qss_icons/rc/radio_unchecked_disabled.png); -} - -QMenu::indicator:exclusive:checked { - image: url(:/qss_icons/rc/radio_checked.png); -} - -QMenu::indicator:exclusive:checked:selected { - image: url(:/qss_icons/rc/radio_checked_disabled.png); -} - -QMenu::right-arrow { - margin: 5px; - image: url(:/qss_icons/rc/right_arrow.png) -} - - -QWidget:disabled -{ - color: #404040; - background-color: #302F2F; -} - -QAbstractItemView -{ - alternate-background-color: #3A3939; - color: silver; - border: 1px solid 3A3939; - border-radius: 2px; - padding: 1px; -} - -QTabWidget:focus, QCheckBox:focus, QRadioButton:focus, QSlider:focus -{ - border: none; -} - -QLineEdit -{ - background-color: #201F1F; - padding: 2px; - border-style: solid; - border: 1px solid #3A3939; - border-radius: 2px; - color: silver; -} - -QGroupBox { - border:1px solid #3A3939; - border-radius: 2px; - margin-top: 20px; -} - -QGroupBox::title { - subcontrol-origin: margin; - subcontrol-position: top center; - padding-left: 10px; - padding-right: 10px; - padding-top: 10px; -} - -QScrollBar:horizontal -{ - height: 15px; - margin: 3px 15px 3px 15px; - border: 1px transparent #2A2929; - border-radius: 4px; - background-color: #2A2929; -} - -QScrollBar::handle:horizontal -{ - background-color: #605F5F; - min-width: 15px; - border-radius: 4px; -} - -QScrollBar::add-line:horizontal -{ - margin: 0px 3px 0px 3px; - border-image: url(:/qss_icons/rc/right_arrow_disabled.png); - width: 10px; - height: 10px; - subcontrol-position: right; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:horizontal -{ - margin: 0px 3px 0px 3px; - border-image: url(:/qss_icons/rc/left_arrow_disabled.png); - height: 10px; - width: 10px; - subcontrol-position: left; - subcontrol-origin: margin; -} - -QScrollBar::add-line:horizontal:hover,QScrollBar::add-line:horizontal:on -{ - border-image: url(:/qss_icons/rc/right_arrow.png); - height: 10px; - width: 10px; - subcontrol-position: right; - subcontrol-origin: margin; -} - - -QScrollBar::sub-line:horizontal:hover, QScrollBar::sub-line:horizontal:on -{ - border-image: url(:/qss_icons/rc/left_arrow.png); - height: 10px; - width: 10px; - subcontrol-position: left; - subcontrol-origin: margin; -} - -QScrollBar::up-arrow:horizontal, QScrollBar::down-arrow:horizontal -{ - background: none; -} - - -QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal -{ - background: none; -} - -QScrollBar:vertical -{ - background-color: #2A2929; - width: 15px; - margin: 15px 3px 15px 3px; - border: 1px transparent #2A2929; - border-radius: 4px; -} - -QScrollBar::handle:vertical -{ - background-color: #605F5F; - min-height: 15px; - border-radius: 4px; -} - -QScrollBar::sub-line:vertical -{ - margin: 3px 0px 3px 0px; - border-image: url(:/qss_icons/rc/up_arrow_disabled.png); - height: 10px; - width: 10px; - subcontrol-position: top; - subcontrol-origin: margin; -} - -QScrollBar::add-line:vertical -{ - margin: 3px 0px 3px 0px; - border-image: url(:/qss_icons/rc/down_arrow_disabled.png); - height: 10px; - width: 10px; - subcontrol-position: bottom; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:vertical:hover,QScrollBar::sub-line:vertical:on -{ - - border-image: url(:/qss_icons/rc/up_arrow.png); - height: 10px; - width: 10px; - subcontrol-position: top; - subcontrol-origin: margin; -} - - -QScrollBar::add-line:vertical:hover, QScrollBar::add-line:vertical:on -{ - border-image: url(:/qss_icons/rc/down_arrow.png); - height: 10px; - width: 10px; - subcontrol-position: bottom; - subcontrol-origin: margin; -} - -QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical -{ - background: none; -} - - -QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical -{ - background: none; -} - -QTextEdit -{ - background-color: #201F1F; - color: silver; - border: 1px solid #3A3939; - margin: 0; -} - -QPlainTextEdit -{ - background-color: #201F1F;; - color: silver; - border-radius: 2px; - border: 1px solid #3A3939; -} - -QHeaderView::section -{ - background-color: #3A3939; - color: silver; - padding-left: 4px; - border: 1px solid #6c6c6c; -} - -QSizeGrip { - image: url(:/qss_icons/rc/sizegrip.png); - width: 12px; - height: 12px; -} - - -QMenu::separator -{ - height: 1px; - background-color: #3A3939; - color: white; - padding-left: 4px; - margin-left: 10px; - margin-right: 5px; -} - -QFrame -{ - border-radius: 2px; - border: 1px solid #444; -} - -QFrame[frameShape="0"] -{ - border-radius: 2px; - border: 1px transparent #444; -} - -QStackedWidget -{ - border: 1px transparent black; -} - -QToolBar { - border: 1px transparent #393838; - background: 1px solid #302F2F; - font-weight: bold; -} - -QPushButton -{ - color: silver; - background-color: #302F2F; - border-width: 1px; - border-color: #202020; - border-style: solid; - padding-top: 5px; - padding-bottom: 5px; - padding-left: 5px; - padding-right: 5px; - border-radius: 5px; - outline: none; -} - -QPushButton:disabled -{ - background-color: #302F2F; - border-width: 1px; - border-color: #3A3939; - border-style: solid; - padding-top: 5px; - padding-bottom: 5px; - padding-left: 10px; - padding-right: 10px; - border-radius: 5px; - color: #454545; -} - -QComboBox -{ - selection-background-color: #3d8ec9; - background-color: #201F1F; - border-style: solid; - border: 1px solid #3A3939; - border-radius: 2px; - padding: 2px; - min-width: 30px; -} - -QPushButton:checked{ -background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0.0 #302F2F, - stop: 0.5 #6a6868, - stop: 1 #302F2F); -} - -QPushButton:hover -{ -background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0.0 #302F2F, stop: 0.4 #4E4D4D, - stop: 0.5 #6a6868, - stop: 0.6 #4E4D4D, stop: 1 #302F2F); -} - -QComboBox:hover,QAbstractSpinBox:hover,QLineEdit:hover,QPlainTextEdit:hover,QAbstractView:hover,QTreeView:hover -{ - border: 1px solid #606060; - color: silver; -} - -QComboBox:on -{ - background-color: #626873; - padding-top: 3px; - padding-left: 4px; - selection-background-color: #4a4a4a; -} - -QComboBox QAbstractItemView -{ - background-color: #201F1F; - border-radius: 2px; - border: 1px solid #444; - selection-background-color: #3d8ec9; -} - -QComboBox::drop-down -{ - subcontrol-origin: padding; - subcontrol-position: top right; - width: 10px; - - border-left-width: 0px; - border-left-color: darkgray; - border-left-style: solid; - border-top-right-radius: 3px; - border-bottom-right-radius: 3px; -} - -QComboBox::down-arrow -{ - image: url(:/qss_icons/rc/down_arrow_disabled.png); -} - -QComboBox::down-arrow:on, QComboBox::down-arrow:hover, -QComboBox::down-arrow:focus -{ - image: url(:/qss_icons/rc/down_arrow.png); -} - -QAbstractSpinBox { - padding-top: 2px; - padding-bottom: 2px; - border: 1px solid #3A3939; - background-color: #201F1F; - color: silver; - border-radius: 2px; - min-width: 60px; -} - -QAbstractSpinBox:up-button -{ - background-color: transparent; - subcontrol-origin: border; - subcontrol-position: center right; -} - -QAbstractSpinBox:down-button -{ - background-color: transparent; - subcontrol-origin: border; - subcontrol-position: center left; -} - -QAbstractSpinBox::up-arrow,QAbstractSpinBox::up-arrow:disabled,QAbstractSpinBox::up-arrow:off { - image: url(:/qss_icons/rc/up_arrow_disabled.png); - width: 10px; - height: 10px; -} -QAbstractSpinBox::up-arrow:hover -{ - image: url(:/qss_icons/rc/up_arrow.png); -} - - -QAbstractSpinBox::down-arrow,QAbstractSpinBox::down-arrow:disabled,QAbstractSpinBox::down-arrow:off -{ - image: url(:/qss_icons/rc/down_arrow_disabled.png); - width: 10px; - height: 10px; -} -QAbstractSpinBox::down-arrow:hover -{ - image: url(:/qss_icons/rc/down_arrow.png); -} - - -QLabel -{ - border: 0px solid black; - margin-left: 2px; - margin-right: 2px; -} - -QTabWidget{ - border: 1px transparent black; -} - -QTabWidget::pane { - border: 1px transparent #444; - border-radius: 3px; - padding: 3px; -} - -QTabBar -{ - qproperty-drawBase: 0; - left: 5px; /* move to the right by 5px */ -} - -QTabBar:focus -{ - border: 0px transparent black; -} - -QTabBar::close-button { - image: url(:/qss_icons/rc/close.png); - background: transparent; -} - -QTabBar::close-button:hover -{ - image: url(:/qss_icons/rc/close-hover.png); - background: transparent; -} - -QTabBar::close-button:pressed { - image: url(:/qss_icons/rc/close-pressed.png); - background: transparent; -} - -/* TOP TABS */ -QTabBar::tab:top { - color: #b1b1b1; - border: 1px solid #4A4949; - border-bottom: 1px transparent black; - background-color: #302F2F; - padding: 5px; - border-top-left-radius: 2px; - border-top-right-radius: 2px; -} - -QTabBar::tab:top:!selected -{ - color: #b1b1b1; - background-color: #201F1F; - border: 1px transparent #4A4949; - border-bottom: 1px transparent #4A4949; - border-top-left-radius: 0px; - border-top-right-radius: 0px; -} - -QTabBar::tab:top:!selected:hover { - background-color: #48576b; -} - -/* BOTTOM TABS */ -QTabBar::tab:bottom { - color: #b1b1b1; - border: 1px solid #4A4949; - border-top: 1px transparent black; - background-color: #302F2F; - padding: 5px; - border-bottom-left-radius: 2px; - border-bottom-right-radius: 2px; -} - -QTabBar::tab:bottom:!selected -{ - color: #b1b1b1; - background-color: #201F1F; - border: 1px transparent #4A4949; - border-top: 1px transparent #4A4949; - border-bottom-left-radius: 0px; - border-bottom-right-radius: 0px; -} - -QTabBar::tab:bottom:!selected:hover { - background-color: #78879b; -} - -/* LEFT TABS */ -QTabBar::tab:left { - color: #b1b1b1; - border: 1px transparent #4A4949; - border-left: 1px transparent black; - background-color: #48576b; - padding: 5px; - border-top-right-radius: 0px; - border-bottom-right-radius: 0px; -} - -QTabBar::tab:left:!selected -{ - color: #b1b1b1; - background-color: #302F2F; - border: 1px transparent #4A4949; - border-right: 1px transparent #4A4949; - border-top-right-radius: 0px; - border-bottom-right-radius: 0px; -} - -QTabBar::tab:left:hover { - background-color: #48576b; -} - -QTabBar::tab:left:disabled -{ - color: #3A3939; - background-color: #302F2F; - border: 1px transparent #4A4949; - border-right: 1px transparent #4A4949; - border-top-right-radius: 0px; - border-bottom-right-radius: 0px; -} - - - -/* RIGHT TABS */ -QTabBar::tab:right { - color: #b1b1b1; - border: 1px solid #4A4949; - border-right: 1px transparent black; - background-color: #302F2F; - padding: 5px; - border-top-left-radius: 2px; - border-bottom-left-radius: 2px; -} - -QTabBar::tab:right:!selected -{ - color: #b1b1b1; - background-color: #201F1F; - border: 1px transparent #4A4949; - border-right: 1px transparent #4A4949; - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; -} - -QTabBar::tab:right:!selected:hover { - background-color: #48576b; -} - -QTabBar QToolButton::right-arrow:enabled { - image: url(:/qss_icons/rc/right_arrow.png); - } - - QTabBar QToolButton::left-arrow:enabled { - image: url(:/qss_icons/rc/left_arrow.png); - } - -QTabBar QToolButton::right-arrow:disabled { - image: url(:/qss_icons/rc/right_arrow_disabled.png); - } - - QTabBar QToolButton::left-arrow:disabled { - image: url(:/qss_icons/rc/left_arrow_disabled.png); - } - - -QDockWidget { - border: 1px transparent #403F3F; - titlebar-close-icon: url(:/qss_icons/rc/close.png); - titlebar-normal-icon: url(:/qss_icons/rc/undock.png); -} - -QDockWidget::title { - border: 1px solid #282727; - background-color: #2b2a2a; -} - -QDockWidget::close-button, QDockWidget::float-button { - border: 1px solid transparent; - border-radius: 2px; - background: transparent; -} - -QDockWidget::close-button:hover, QDockWidget::float-button:hover { - background: rgba(255, 255, 255, 10); -} - -QDockWidget::close-button:pressed, QDockWidget::float-button:pressed { - padding: 1px -1px -1px 1px; - background: rgba(255, 255, 255, 10); -} - -QTreeView, QListView -{ - border: 1px solid #444; - background-color: #201F1F; -} - -QTreeView:branch:selected, QTreeView:branch:hover -{ - background: url(:/qss_icons/rc/transparent.png); -} - -QTreeView::branch:has-siblings:!adjoins-item { - border-image: url(:/qss_icons/rc/transparent.png); -} - -QTreeView::branch:has-siblings:adjoins-item { - border-image: url(:/qss_icons/rc/transparent.png); -} - -QTreeView::branch:!has-children:!has-siblings:adjoins-item { - border-image: url(:/qss_icons/rc/transparent.png); -} - -QTreeView::branch:has-children:!has-siblings:closed, -QTreeView::branch:closed:has-children:has-siblings { - image: url(:/qss_icons/rc/branch_closed.png); -} - -QTreeView::branch:open:has-children:!has-siblings, -QTreeView::branch:open:has-children:has-siblings { - image: url(:/qss_icons/rc/branch_open.png); -} - -QTreeView::branch:has-children:!has-siblings:closed:hover, -QTreeView::branch:closed:has-children:has-siblings:hover { - image: url(:/qss_icons/rc/branch_closed-on.png); - } - -QTreeView::branch:open:has-children:!has-siblings:hover, -QTreeView::branch:open:has-children:has-siblings:hover { - image: url(:/qss_icons/rc/branch_open-on.png); - } - -QListView::item:!selected:hover, QListView::item:!selected:hover, QTreeView::item:!selected:hover { - background: rgba(0, 0, 0, 0); - outline: 0; - color: #FFFFFF -} - -QListView::item:selected:hover, QListView::item:selected:hover, QTreeView::item:selected:hover { - background: #3d8ec9; - color: #FFFFFF; -} - -QSlider::groove:horizontal { - border: 1px solid #3A3939; - height: 8px; - background: #201F1F; - margin: 2px 0; - border-radius: 2px; -} - -QSlider::groove:horizontal:disabled { - border: 1px solid #3A3939; - height: 8px; - background: #282727; - margin: 2px 0; - border-radius: 2px; -} - -QSlider::handle:horizontal { - background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0.0 silver, stop: 0.2 #a8a8a8, stop: 1 #727272); - border: 1px solid #3A3939; - width: 10px; - height: 14px; - margin: -4px 0; - border-radius: 2px; -} - -QSlider::handle:horizontal:disabled { - background: #4A4949; - border: 1px solid #3A3939; - width: 10px; - height: 14px; - margin: -4px 0; - border-radius: 2px; -} - -QSlider::groove:vertical { - border: 1px solid #3A3939; - width: 8px; - background: #201F1F; - margin: 0 0px; - border-radius: 2px; -} - -QSlider::groove:vertical:disabled { - border: 1px solid #3A3939; - height: 8px; - background: #403F3F; - margin: 2px 0; - border-radius: 2px; -} - -QSlider::handle:vertical { - background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0.0 silver, - stop: 0.2 #a8a8a8, stop: 1 #727272); - border: 1px solid #3A3939; - width: 14px; - height: 10px; - margin: 0 -4px; - border-radius: 2px; -} - -QSlider::handle:vertical:disabled { - background: #4A4949; - border: 1px solid #3A3939; - width: 14px; - height: 10px; - margin: 0 -4px; - border-radius: 2px; -} - -QToolButton#MaximizeButton { - background-color: transparent; - border-left: 1px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0.0 #302F2F, stop: 0.3 #606060, - stop: 0.5 #707070, - stop: 0.7 #606060, stop: 1 #302F2F); - border-right: 1px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0.0 #302F2F, stop: 0.3 #606060, - stop: 0.5 #707070, - stop: 0.7 #606060, stop: 1 #302F2F); - border-radius: 0px; - margin: 0px; - padding: 0px; -} - -QToolButton#MinimizeButton, -QToolButton#CloseButton { - background-color: transparent; - border: 1px transparent #808080; - border-radius: 0px; - margin: 0px; - padding: 0px; -} - -QToolButton#MinimizeButton:hover, QToolButton#MinimizeButton::menu-button:hover, -QToolButton#MaximizeButton:hover, QToolButton#MaximizeButton::menu-button:hover{ - background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0.0 #302F2F, stop: 0.4 #4E4D4D, - stop: 0.5 #4A4949, - stop: 0.6 #4E4D4D, stop: 1 #302F2F); -} - -QToolButton#CloseButton:hover, QToolButton#CloseButton::menu-button:hover { -background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0.0 #302F2F, stop: 0.2 #A82F2F, - stop: 0.5 #E83E4A, - stop: 0.8 #A82F2F, stop: 1 #302F2F); -} - -QToolButton { - background-color: transparent; - border: 1px transparent #4A4949; - border-radius: 2px; - margin: 3px; - padding: 3px; -} - -QToolButton[popupMode="1"] { /* only for MenuButtonPopup */ - padding-right: 20px; /* make way for the popup button */ - border: 1px transparent #4A4949; - border-radius: 5px; -} - -QToolButton[popupMode="2"] { /* only for InstantPopup */ - padding-right: 10px; /* make way for the popup button */ - border: 1px transparent #4A4949; -} - - -QToolButton:hover, QToolButton::menu-button:hover { - background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0.0 #302F2F, stop: 0.4 #4E4D4D, - stop: 0.5 #4A4949, - stop: 0.6 #4E4D4D, stop: 1 #302F2F); -} - -QToolButton:checked, QToolButton:pressed, -QToolButton::menu-button:pressed { - background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0.0 #302F2F, - stop: 0.5 #4A4949, - stop: 1.0 #302F2F); -} - -/* the subcontrol below is used only in the InstantPopup or DelayedPopup mode */ -QToolButton::menu-indicator { - image: url(:/qss_icons/rc/down_arrow.png); - top: -7px; left: -2px; /* shift it a bit */ -} - -/* the subcontrols below are used only in the MenuButtonPopup mode */ -QToolButton::menu-button { - border: 1px transparent #4A4949; - border-top-right-radius: 6px; - border-bottom-right-radius: 6px; - /* 16px width + 4px for border = 20px allocated above */ - width: 16px; - outline: none; -} - -QToolButton::menu-arrow { - image: url(:/qss_icons/rc/down_arrow.png); -} - -QToolButton::menu-arrow:open { - top: 1px; left: 1px; /* shift it a bit */ - border: 1px solid #3A3939; -} - -QPushButton::menu-indicator { - subcontrol-origin: padding; - subcontrol-position: bottom right; - left: 8px; -} - -QTableView -{ - border: 1px transparent #444; - gridline-color: #6c6c6c; - background-color: #201F1F; -} - - -QTableView, QHeaderView -{ - border-radius: 0px; -} - -QTableView::item:pressed, QListView::item:pressed, QTreeView::item:pressed { - background: #78879b; - color: #FFFFFF; -} - -QTableView::item:selected:active, QTreeView::item:selected:active, QListView::item:selected:active { - background: #3d8ec9; - color: #FFFFFF; -} - -QHeaderView -{ - border: 1px transparent; - border-radius: 2px; - margin: 0px; - padding: 0px; -} - -QHeaderView::section { - background-color: #302F2F; - color: silver; - padding: 4px; - border: 1px transparent #6c6c6c; - border-radius: 0px; - text-align: center; -} - -QHeaderView::section::vertical::first, QHeaderView::section::vertical::only-one -{ - border-top: 1px transparent #6c6c6c; -} - -QHeaderView::section::vertical -{ - border-top: transparent; -} - -QHeaderView::section::horizontal::first, QHeaderView::section::horizontal::only-one -{ - border-left: 1px transparent #6c6c6c; -} - -QHeaderView::section::horizontal -{ - border-left: transparent; -} - - -QHeaderView::section:checked - { - color: white; - background-color: #5A5959; - } - - /* style the sort indicator */ -QHeaderView::down-arrow { - image: url(:/qss_icons/rc/down_arrow.png); -} - -QHeaderView::up-arrow { - image: url(:/qss_icons/rc/up_arrow.png); -} - - -QTableCornerButton::section { - background-color: #3A3939; - border: 1px solid #3A3939; - border-radius: 2px; -} - -QToolBox { - padding: 3px; - border: 1px transparent black; -} - -QToolBox::tab { - color: #b1b1b1; - background-color: #302F2F; - border: 1px solid #4A4949; - border-bottom: 1px transparent #302F2F; - border-top-left-radius: 5px; - border-top-right-radius: 5px; -} - - QToolBox::tab:selected { /* italicize selected tabs */ - font: italic; - background-color: #302F2F; - border-color: #3d8ec9; - } - -QStatusBar::item { - border: 1px solid #3A3939; - border-radius: 2px; - } - -QFrame[height="3"], QFrame[width="3"] { - background-color: #444; -} - -QAbstractScrollArea -{ - border-radius: 2px; - border: 0px transparent #3A3939; - background-color: #302F2F; -} - -QSplitter::handle:horizontal, -QMainWindow::separator -{ - background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0.0 #302F2F, - stop: 0.4 #333333, - stop: 0.5 #404040, - stop: 0.6 #333333, - stop: 1 #302F2F); - color: white; - padding-left: 0px; - spacing: 0px; - width: 3px; - border: 0px solid #202020; -} - -QSplitter::handle:horizontal:hover, -QMainWindow::separator:hover -{ - background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0.0 #302F2F, - stop: 0.1 #333333, - stop: 0.5 #404040, - stop: 0.9 #333333, - stop: 1 #302F2F); - color: white; - padding-left: 0px; - spacing: 0px; - width: 3px; - border: 0px solid #202020; -} - -QSplitter::handle:vertical { - background-color: QLinearGradient( x1: 0, y1: 0, x2: 1, y2: 0, - stop: 0.0 #302F2F, - stop: 0.3 #505050, - stop: 0.5 #606060, - stop: 0.7 #505050, - stop: 1 #302F2F); - height: 3px; -} - -QSplitter::handle:vertical:hover { - background-color: QLinearGradient( x1: 0, y1: 0, x2: 1, y2: 0, - stop: 0.0 #302F2F, - stop: 0.1 #505050, - stop: 0.5 #606060, - stop: 0.8 #505050, - stop: 1 #302F2F); - height: 3px; -} diff --git a/DSView/dsapplication.cpp b/DSView/dsapplication.cpp old mode 100644 new mode 100755 diff --git a/DSView/dsapplication.h b/DSView/dsapplication.h old mode 100644 new mode 100755 diff --git a/DSView/extdef.h b/DSView/extdef.h old mode 100644 new mode 100755 diff --git a/DSView/icons/Blackman.png b/DSView/icons/Blackman.png old mode 100644 new mode 100755 diff --git a/DSView/icons/Chinese.png b/DSView/icons/Chinese.png new file mode 100755 index 0000000000000000000000000000000000000000..f138711303a1dcc7a23adb8ce2a180175ee44fb6 Binary files /dev/null and b/DSView/icons/Chinese.png differ diff --git a/DSView/icons/English.png b/DSView/icons/English.png new file mode 100755 index 0000000000000000000000000000000000000000..deee73f0f48a02f1ab6ced271d0dc876f602eddb Binary files /dev/null and b/DSView/icons/English.png differ diff --git a/DSView/icons/Flat_top.png b/DSView/icons/Flat_top.png old mode 100644 new mode 100755 diff --git a/DSView/icons/Hamming.png b/DSView/icons/Hamming.png old mode 100644 new mode 100755 diff --git a/DSView/icons/Hann.png b/DSView/icons/Hann.png old mode 100644 new mode 100755 diff --git a/DSView/icons/Rectangle.png b/DSView/icons/Rectangle.png old mode 100644 new mode 100755 diff --git a/DSView/icons/arrow-loop.png b/DSView/icons/arrow-loop.png deleted file mode 100755 index d3df3243d4e4cc3a43f4d6547bd8a15580dcea38..0000000000000000000000000000000000000000 Binary files a/DSView/icons/arrow-loop.png and /dev/null differ diff --git a/DSView/icons/close.png b/DSView/icons/close.png deleted file mode 100644 index 529f2ed10e43787bbd9fda3fa60703185ac607d3..0000000000000000000000000000000000000000 Binary files a/DSView/icons/close.png and /dev/null differ diff --git a/DSView/icons/about.png b/DSView/icons/dark/about.png similarity index 100% rename from DSView/icons/about.png rename to DSView/icons/dark/about.png diff --git a/DSView/icons/add.png b/DSView/icons/dark/add.png similarity index 100% rename from DSView/icons/add.png rename to DSView/icons/dark/add.png diff --git a/DSView/icons/bug.png b/DSView/icons/dark/bug.png similarity index 100% rename from DSView/icons/bug.png rename to DSView/icons/dark/bug.png diff --git a/DSView/icons/capture.png b/DSView/icons/dark/capture.png old mode 100644 new mode 100755 similarity index 100% rename from DSView/icons/capture.png rename to DSView/icons/dark/capture.png diff --git a/DSView/icons/dark/close.png b/DSView/icons/dark/close.png new file mode 100755 index 0000000000000000000000000000000000000000..8eb85178daae840b51054b777f5d3ca7282c6775 Binary files /dev/null and b/DSView/icons/dark/close.png differ diff --git a/DSView/icons/dark/daq.png b/DSView/icons/dark/daq.png new file mode 100755 index 0000000000000000000000000000000000000000..69be862f9fd8e9f6ff93d82b298a1bafcf8b69ac Binary files /dev/null and b/DSView/icons/dark/daq.png differ diff --git a/DSView/icons/dark/dark.png b/DSView/icons/dark/dark.png new file mode 100755 index 0000000000000000000000000000000000000000..8f822aa8d7222160ee7337f2b6fc7ab40eb3c944 Binary files /dev/null and b/DSView/icons/dark/dark.png differ diff --git a/DSView/icons/del.png b/DSView/icons/dark/del.png similarity index 100% rename from DSView/icons/del.png rename to DSView/icons/dark/del.png diff --git a/DSView/icons/dark/display.png b/DSView/icons/dark/display.png new file mode 100755 index 0000000000000000000000000000000000000000..6ca6c96e2eda2127276120cf860d5346220918eb Binary files /dev/null and b/DSView/icons/dark/display.png differ diff --git a/DSView/icons/down-arrow.png b/DSView/icons/dark/down-arrow.png old mode 100644 new mode 100755 similarity index 100% rename from DSView/icons/down-arrow.png rename to DSView/icons/dark/down-arrow.png diff --git a/DSView/icons/export.png b/DSView/icons/dark/export.png old mode 100644 new mode 100755 similarity index 100% rename from DSView/icons/export.png rename to DSView/icons/dark/export.png diff --git a/DSView/icons/fft.png b/DSView/icons/dark/fft.png old mode 100644 new mode 100755 similarity index 100% rename from DSView/icons/fft.png rename to DSView/icons/dark/fft.png diff --git a/DSView/icons/dark/file.png b/DSView/icons/dark/file.png new file mode 100755 index 0000000000000000000000000000000000000000..926ac2462da2a8f010295daaf06ff940772717b3 Binary files /dev/null and b/DSView/icons/dark/file.png differ diff --git a/DSView/icons/dark/function.png b/DSView/icons/dark/function.png new file mode 100755 index 0000000000000000000000000000000000000000..718edebb30db9cbbf4957e7e98d10eba0a36fa53 Binary files /dev/null and b/DSView/icons/dark/function.png differ diff --git a/DSView/icons/gear.png b/DSView/icons/dark/gear.png old mode 100644 new mode 100755 similarity index 100% rename from DSView/icons/gear.png rename to DSView/icons/dark/gear.png diff --git a/DSView/icons/hidden.png b/DSView/icons/dark/hidden.png old mode 100644 new mode 100755 similarity index 100% rename from DSView/icons/hidden.png rename to DSView/icons/dark/hidden.png diff --git a/DSView/icons/dark/instant.png b/DSView/icons/dark/instant.png new file mode 100755 index 0000000000000000000000000000000000000000..c74c674cef9f046fa09a90bd3d31e055df48f66b Binary files /dev/null and b/DSView/icons/dark/instant.png differ diff --git a/DSView/icons/dark/la.png b/DSView/icons/dark/la.png new file mode 100755 index 0000000000000000000000000000000000000000..d77009bb3f9a6f6c5e7ffedfdf96055d1a4b5368 Binary files /dev/null and b/DSView/icons/dark/la.png differ diff --git a/DSView/icons/dark/light.png b/DSView/icons/dark/light.png new file mode 100755 index 0000000000000000000000000000000000000000..23882479a6df1ee0c0cd708da3bcd782a8d3995e Binary files /dev/null and b/DSView/icons/dark/light.png differ diff --git a/DSView/icons/dark/lissajous.png b/DSView/icons/dark/lissajous.png new file mode 100755 index 0000000000000000000000000000000000000000..632a722d6df8ea209ad74efcd92d3d94b5dde7c9 Binary files /dev/null and b/DSView/icons/dark/lissajous.png differ diff --git a/DSView/icons/dark/logo_color.png b/DSView/icons/dark/logo_color.png new file mode 100755 index 0000000000000000000000000000000000000000..65ae5c6d2bb4831c57fe6200ff3506d2ebdd5d55 Binary files /dev/null and b/DSView/icons/dark/logo_color.png differ diff --git a/DSView/icons/dark/logo_noColor.png b/DSView/icons/dark/logo_noColor.png new file mode 100755 index 0000000000000000000000000000000000000000..9ee4aad67c743a02f2610cde5e93db4066530e69 Binary files /dev/null and b/DSView/icons/dark/logo_noColor.png differ diff --git a/DSView/icons/manual.png b/DSView/icons/dark/manual.png similarity index 100% rename from DSView/icons/manual.png rename to DSView/icons/dark/manual.png diff --git a/DSView/icons/dark/math.png b/DSView/icons/dark/math.png new file mode 100755 index 0000000000000000000000000000000000000000..f84625f7960e3339cca0cb05e0c5f1238e926c7a Binary files /dev/null and b/DSView/icons/dark/math.png differ diff --git a/DSView/icons/dark/maximize.png b/DSView/icons/dark/maximize.png new file mode 100755 index 0000000000000000000000000000000000000000..51d6577aa612a64af060b8ab73a4c1e070e6e2a0 Binary files /dev/null and b/DSView/icons/dark/maximize.png differ diff --git a/DSView/icons/dark/measure.png b/DSView/icons/dark/measure.png new file mode 100755 index 0000000000000000000000000000000000000000..d0ce0421faae356cd85af1ebd04df75a952eda4c Binary files /dev/null and b/DSView/icons/dark/measure.png differ diff --git a/DSView/icons/dark/minimize.png b/DSView/icons/dark/minimize.png new file mode 100755 index 0000000000000000000000000000000000000000..132ef21c0092ddaf26e3a485e5cc231b9b944057 Binary files /dev/null and b/DSView/icons/dark/minimize.png differ diff --git a/DSView/icons/dark/moder.png b/DSView/icons/dark/moder.png new file mode 100755 index 0000000000000000000000000000000000000000..0f13a3fcc1e9f29afbf722a8cb6d5e330f9911ef Binary files /dev/null and b/DSView/icons/dark/moder.png differ diff --git a/DSView/icons/dark/modes.png b/DSView/icons/dark/modes.png new file mode 100755 index 0000000000000000000000000000000000000000..fca07844146e35b59ef228e2230bff29a3fe728b Binary files /dev/null and b/DSView/icons/dark/modes.png differ diff --git a/DSView/icons/nav.png b/DSView/icons/dark/nav.png similarity index 100% rename from DSView/icons/nav.png rename to DSView/icons/dark/nav.png diff --git a/DSView/icons/next.png b/DSView/icons/dark/next.png old mode 100644 new mode 100755 similarity index 100% rename from DSView/icons/next.png rename to DSView/icons/dark/next.png diff --git a/DSView/icons/oneloop.png b/DSView/icons/dark/oneloop.png similarity index 100% rename from DSView/icons/oneloop.png rename to DSView/icons/dark/oneloop.png diff --git a/DSView/icons/open.png b/DSView/icons/dark/open.png old mode 100644 new mode 100755 similarity index 100% rename from DSView/icons/open.png rename to DSView/icons/dark/open.png diff --git a/DSView/icons/dark/osc.png b/DSView/icons/dark/osc.png new file mode 100755 index 0000000000000000000000000000000000000000..233027f6817f44dfdc009ab4fa24c7dae30f993b Binary files /dev/null and b/DSView/icons/dark/osc.png differ diff --git a/DSView/icons/dark/params.png b/DSView/icons/dark/params.png new file mode 100755 index 0000000000000000000000000000000000000000..e64cd54b208ba1cb908a7c02f87d9afedb58dc5e Binary files /dev/null and b/DSView/icons/dark/params.png differ diff --git a/DSView/icons/pre.png b/DSView/icons/dark/pre.png old mode 100644 new mode 100755 similarity index 100% rename from DSView/icons/pre.png rename to DSView/icons/dark/pre.png diff --git a/DSView/icons/dark/protocol.png b/DSView/icons/dark/protocol.png new file mode 100755 index 0000000000000000000000000000000000000000..75378de680f31367af88722760efb9dd528002b6 Binary files /dev/null and b/DSView/icons/dark/protocol.png differ diff --git a/DSView/icons/repeat.png b/DSView/icons/dark/repeat.png similarity index 100% rename from DSView/icons/repeat.png rename to DSView/icons/dark/repeat.png diff --git a/DSView/icons/dark/restore.png b/DSView/icons/dark/restore.png new file mode 100755 index 0000000000000000000000000000000000000000..2079882a76e044e1c68d967e15dc0965120e8785 Binary files /dev/null and b/DSView/icons/dark/restore.png differ diff --git a/DSView/icons/save.png b/DSView/icons/dark/save.png old mode 100644 new mode 100755 similarity index 100% rename from DSView/icons/save.png rename to DSView/icons/dark/save.png diff --git a/DSView/icons/dark/search-bar.png b/DSView/icons/dark/search-bar.png new file mode 100755 index 0000000000000000000000000000000000000000..e3a3298f0187a3374791d1fef3eed8a922223df8 Binary files /dev/null and b/DSView/icons/dark/search-bar.png differ diff --git a/DSView/icons/dark/search.png b/DSView/icons/dark/search.png new file mode 100755 index 0000000000000000000000000000000000000000..5a67758ef6a0fb268a29a71f5e5dff8a632b4f71 Binary files /dev/null and b/DSView/icons/dark/search.png differ diff --git a/DSView/icons/shown.png b/DSView/icons/dark/shown.png old mode 100644 new mode 100755 similarity index 100% rename from DSView/icons/shown.png rename to DSView/icons/dark/shown.png diff --git a/DSView/icons/dark/single.png b/DSView/icons/dark/single.png new file mode 100755 index 0000000000000000000000000000000000000000..4c44569802e738914e43c554f64a387a6928bfd1 Binary files /dev/null and b/DSView/icons/dark/single.png differ diff --git a/DSView/icons/dark/start.png b/DSView/icons/dark/start.png new file mode 100755 index 0000000000000000000000000000000000000000..40e181d08fb6b97d2dc8ffc2882b8ff1fdc229cc Binary files /dev/null and b/DSView/icons/dark/start.png differ diff --git a/DSView/icons/dark/stop.png b/DSView/icons/dark/stop.png new file mode 100755 index 0000000000000000000000000000000000000000..7017ec467280334d4a5192681c5e16a8b78f6f3a Binary files /dev/null and b/DSView/icons/dark/stop.png differ diff --git a/DSView/icons/support.png b/DSView/icons/dark/support.png similarity index 100% rename from DSView/icons/support.png rename to DSView/icons/dark/support.png diff --git a/DSView/icons/dark/trigger.png b/DSView/icons/dark/trigger.png new file mode 100755 index 0000000000000000000000000000000000000000..9ccd6c0c8e203183b229d90eea7f506bf39608a4 Binary files /dev/null and b/DSView/icons/dark/trigger.png differ diff --git a/DSView/icons/dark/wait.gif b/DSView/icons/dark/wait.gif new file mode 100755 index 0000000000000000000000000000000000000000..8cff358c7859c14f9768531328fdcfdc7f8f5a6f Binary files /dev/null and b/DSView/icons/dark/wait.gif differ diff --git a/DSView/icons/del_dis.png b/DSView/icons/del_dis.png deleted file mode 100755 index d4f418c34e7b466334fd3d2d55e3816e0c3ac048..0000000000000000000000000000000000000000 Binary files a/DSView/icons/del_dis.png and /dev/null differ diff --git a/DSView/icons/file.png b/DSView/icons/file.png deleted file mode 100644 index 78c469cc13bf521c2874e3235ab4d0f9ba9c70ab..0000000000000000000000000000000000000000 Binary files a/DSView/icons/file.png and /dev/null differ diff --git a/DSView/icons/file_dis.png b/DSView/icons/file_dis.png deleted file mode 100644 index 5c27e1aee3179f32ab81f94a3d6829fc4951b98c..0000000000000000000000000000000000000000 Binary files a/DSView/icons/file_dis.png and /dev/null differ diff --git a/DSView/icons/instant.png b/DSView/icons/instant.png deleted file mode 100644 index c3e249d3732fe960f037ce142a99a624616727a9..0000000000000000000000000000000000000000 Binary files a/DSView/icons/instant.png and /dev/null differ diff --git a/DSView/icons/instant_dis.png b/DSView/icons/instant_dis.png deleted file mode 100644 index 9c24bf07831aed72d80998e1c49c5363abae5ab0..0000000000000000000000000000000000000000 Binary files a/DSView/icons/instant_dis.png and /dev/null differ diff --git a/DSView/icons/light/about.png b/DSView/icons/light/about.png new file mode 100755 index 0000000000000000000000000000000000000000..e1810a34088bcb1afc73cd7e7061b6224dd11d51 Binary files /dev/null and b/DSView/icons/light/about.png differ diff --git a/DSView/icons/add_dis.png b/DSView/icons/light/add.png similarity index 50% rename from DSView/icons/add_dis.png rename to DSView/icons/light/add.png index b0349001446dd2c939e26bacb484377b56703652..fdb05911e5b0e9150815bc65182937aaa16ba20e 100755 Binary files a/DSView/icons/add_dis.png and b/DSView/icons/light/add.png differ diff --git a/DSView/icons/light/bug.png b/DSView/icons/light/bug.png new file mode 100755 index 0000000000000000000000000000000000000000..56b70a64bdccf3b0da6297a285ae01e4c69cda03 Binary files /dev/null and b/DSView/icons/light/bug.png differ diff --git a/DSView/icons/light/capture.png b/DSView/icons/light/capture.png new file mode 100755 index 0000000000000000000000000000000000000000..f581e561d7ccbf2d0cb58c0b95782153fb2f5674 Binary files /dev/null and b/DSView/icons/light/capture.png differ diff --git a/DSView/icons/light/close.png b/DSView/icons/light/close.png new file mode 100755 index 0000000000000000000000000000000000000000..a3de9ec9696f8676419c3d027d3e22ce31408c6e Binary files /dev/null and b/DSView/icons/light/close.png differ diff --git a/DSView/icons/light/daq.png b/DSView/icons/light/daq.png new file mode 100755 index 0000000000000000000000000000000000000000..ac80361f39725ac47a103c9332dfa2db5e198efe Binary files /dev/null and b/DSView/icons/light/daq.png differ diff --git a/DSView/icons/light/dark.png b/DSView/icons/light/dark.png new file mode 100755 index 0000000000000000000000000000000000000000..889cac2b84021474adea0d0b86f7501d04a317ac Binary files /dev/null and b/DSView/icons/light/dark.png differ diff --git a/DSView/icons/light/del.png b/DSView/icons/light/del.png new file mode 100755 index 0000000000000000000000000000000000000000..d361cfe3b38d5ee94504c6aaea36569ee9b1b00b Binary files /dev/null and b/DSView/icons/light/del.png differ diff --git a/DSView/icons/light/display.png b/DSView/icons/light/display.png new file mode 100755 index 0000000000000000000000000000000000000000..966d0e5a76a2d0abfb6935d2a70b434028472bc0 Binary files /dev/null and b/DSView/icons/light/display.png differ diff --git a/DSView/icons/light/down-arrow.png b/DSView/icons/light/down-arrow.png new file mode 100755 index 0000000000000000000000000000000000000000..d1b987efb402596e0d9a60954b0c91cff68a5ce3 Binary files /dev/null and b/DSView/icons/light/down-arrow.png differ diff --git a/DSView/icons/light/export.png b/DSView/icons/light/export.png new file mode 100755 index 0000000000000000000000000000000000000000..02b237608fe0b2d19a2e784eecb74babfa12381a Binary files /dev/null and b/DSView/icons/light/export.png differ diff --git a/DSView/icons/light/fft.png b/DSView/icons/light/fft.png new file mode 100755 index 0000000000000000000000000000000000000000..cc26ab4977f351836de9f5c6c4b627f4f1af7b36 Binary files /dev/null and b/DSView/icons/light/fft.png differ diff --git a/DSView/icons/light/file.png b/DSView/icons/light/file.png new file mode 100755 index 0000000000000000000000000000000000000000..4dfc6ae949ff67eb53a21994911bd5af7e9dd591 Binary files /dev/null and b/DSView/icons/light/file.png differ diff --git a/DSView/icons/light/function.png b/DSView/icons/light/function.png new file mode 100755 index 0000000000000000000000000000000000000000..9092101926b17f15dba89c88f4c15786c36e8c8d Binary files /dev/null and b/DSView/icons/light/function.png differ diff --git a/DSView/icons/light/gear.png b/DSView/icons/light/gear.png new file mode 100755 index 0000000000000000000000000000000000000000..794195c65030b1a8ae706352b299ae9200a1f023 Binary files /dev/null and b/DSView/icons/light/gear.png differ diff --git a/DSView/icons/light/hidden.png b/DSView/icons/light/hidden.png new file mode 100755 index 0000000000000000000000000000000000000000..427eaa41d6bf38baf68268b2ebd02a04578d9ad6 Binary files /dev/null and b/DSView/icons/light/hidden.png differ diff --git a/DSView/icons/light/instant.png b/DSView/icons/light/instant.png new file mode 100755 index 0000000000000000000000000000000000000000..8acd5871abb3acb61e7e066f54ed90fde5734841 Binary files /dev/null and b/DSView/icons/light/instant.png differ diff --git a/DSView/icons/light/la.png b/DSView/icons/light/la.png new file mode 100755 index 0000000000000000000000000000000000000000..25a361aa03e40934de86d0ca7f06f725e569b1a1 Binary files /dev/null and b/DSView/icons/light/la.png differ diff --git a/DSView/icons/light/light.png b/DSView/icons/light/light.png new file mode 100755 index 0000000000000000000000000000000000000000..ab90576cabd1f782c2cb5a83b2f59367b859fdb5 Binary files /dev/null and b/DSView/icons/light/light.png differ diff --git a/DSView/icons/light/lissajous.png b/DSView/icons/light/lissajous.png new file mode 100755 index 0000000000000000000000000000000000000000..868be40afe0e057e0144662b88218b871c67048b Binary files /dev/null and b/DSView/icons/light/lissajous.png differ diff --git a/DSView/icons/light/logo_color.png b/DSView/icons/light/logo_color.png new file mode 100755 index 0000000000000000000000000000000000000000..65ae5c6d2bb4831c57fe6200ff3506d2ebdd5d55 Binary files /dev/null and b/DSView/icons/light/logo_color.png differ diff --git a/DSView/icons/light/logo_noColor.png b/DSView/icons/light/logo_noColor.png new file mode 100755 index 0000000000000000000000000000000000000000..3a39b2e852ef51030cf38f1436a8fba4eb2c19d0 Binary files /dev/null and b/DSView/icons/light/logo_noColor.png differ diff --git a/DSView/icons/light/manual.png b/DSView/icons/light/manual.png new file mode 100755 index 0000000000000000000000000000000000000000..b0b6a71f33b87a93932eb6c2cfb69e89e25dec7d Binary files /dev/null and b/DSView/icons/light/manual.png differ diff --git a/DSView/icons/light/math.png b/DSView/icons/light/math.png new file mode 100755 index 0000000000000000000000000000000000000000..39168f0d8ca2990b85bf3b24ce2465c2a2fcac6a Binary files /dev/null and b/DSView/icons/light/math.png differ diff --git a/DSView/icons/light/maximize.png b/DSView/icons/light/maximize.png new file mode 100755 index 0000000000000000000000000000000000000000..08d9385395e8627c5d1a9c52d9e425498d04e710 Binary files /dev/null and b/DSView/icons/light/maximize.png differ diff --git a/DSView/icons/light/measure.png b/DSView/icons/light/measure.png new file mode 100755 index 0000000000000000000000000000000000000000..41c711e7dc5828b4310fbccc39f2d00993df8694 Binary files /dev/null and b/DSView/icons/light/measure.png differ diff --git a/DSView/icons/light/minimize.png b/DSView/icons/light/minimize.png new file mode 100755 index 0000000000000000000000000000000000000000..e4be4c91033a0c4bcf24c294434aec05b89f96fe Binary files /dev/null and b/DSView/icons/light/minimize.png differ diff --git a/DSView/icons/light/moder.png b/DSView/icons/light/moder.png new file mode 100755 index 0000000000000000000000000000000000000000..09e01af27efe98949ce6461777b522f70b6095c4 Binary files /dev/null and b/DSView/icons/light/moder.png differ diff --git a/DSView/icons/light/modes.png b/DSView/icons/light/modes.png new file mode 100755 index 0000000000000000000000000000000000000000..62a348b05430710396f2193e4211bea48e396b83 Binary files /dev/null and b/DSView/icons/light/modes.png differ diff --git a/DSView/icons/light/nav.png b/DSView/icons/light/nav.png new file mode 100755 index 0000000000000000000000000000000000000000..1f5736727d19ac43d6ba709e31316a15fab36d38 Binary files /dev/null and b/DSView/icons/light/nav.png differ diff --git a/DSView/icons/light/next.png b/DSView/icons/light/next.png new file mode 100755 index 0000000000000000000000000000000000000000..ebec6e154a750e7b9e183babc314293acdc29b31 Binary files /dev/null and b/DSView/icons/light/next.png differ diff --git a/DSView/icons/light/oneloop.png b/DSView/icons/light/oneloop.png new file mode 100755 index 0000000000000000000000000000000000000000..4eee0d71f4b5d2f0e88836323b648414c9b4250b Binary files /dev/null and b/DSView/icons/light/oneloop.png differ diff --git a/DSView/icons/light/open.png b/DSView/icons/light/open.png new file mode 100755 index 0000000000000000000000000000000000000000..38cd27cb0a191c070d0378136f3324fcbcdea245 Binary files /dev/null and b/DSView/icons/light/open.png differ diff --git a/DSView/icons/light/osc.png b/DSView/icons/light/osc.png new file mode 100755 index 0000000000000000000000000000000000000000..2811d95de0b2e02096dd58276a4b44a1c71e1d38 Binary files /dev/null and b/DSView/icons/light/osc.png differ diff --git a/DSView/icons/light/params.png b/DSView/icons/light/params.png new file mode 100755 index 0000000000000000000000000000000000000000..6531faa964ed18cfecbd0b19d5f33f485ef07bb9 Binary files /dev/null and b/DSView/icons/light/params.png differ diff --git a/DSView/icons/light/pre.png b/DSView/icons/light/pre.png new file mode 100755 index 0000000000000000000000000000000000000000..600842db8641d3ab0f332ea01c81f0ac99cea4cd Binary files /dev/null and b/DSView/icons/light/pre.png differ diff --git a/DSView/icons/light/protocol.png b/DSView/icons/light/protocol.png new file mode 100755 index 0000000000000000000000000000000000000000..a726aab69b8001b587e862de44aff278aca423d7 Binary files /dev/null and b/DSView/icons/light/protocol.png differ diff --git a/DSView/icons/light/repeat.png b/DSView/icons/light/repeat.png new file mode 100755 index 0000000000000000000000000000000000000000..2a5826560df458b8cf3564a8d49fde085cbc081c Binary files /dev/null and b/DSView/icons/light/repeat.png differ diff --git a/DSView/icons/light/restore.png b/DSView/icons/light/restore.png new file mode 100755 index 0000000000000000000000000000000000000000..adc7957aeed37c7c5f6594b789ffcd77c454f8d4 Binary files /dev/null and b/DSView/icons/light/restore.png differ diff --git a/DSView/icons/light/save.png b/DSView/icons/light/save.png new file mode 100755 index 0000000000000000000000000000000000000000..60804f4c2abf378ce859d9929a3fcde474bca16b Binary files /dev/null and b/DSView/icons/light/save.png differ diff --git a/DSView/icons/light/search-bar.png b/DSView/icons/light/search-bar.png new file mode 100755 index 0000000000000000000000000000000000000000..5f85363cf2ab2fd329c8456418ceb5e9e16b56f4 Binary files /dev/null and b/DSView/icons/light/search-bar.png differ diff --git a/DSView/icons/light/search.png b/DSView/icons/light/search.png new file mode 100755 index 0000000000000000000000000000000000000000..5a67758ef6a0fb268a29a71f5e5dff8a632b4f71 Binary files /dev/null and b/DSView/icons/light/search.png differ diff --git a/DSView/icons/light/shown.png b/DSView/icons/light/shown.png new file mode 100755 index 0000000000000000000000000000000000000000..cab7c021bccc43f3a2cc9cf069d877e222911d72 Binary files /dev/null and b/DSView/icons/light/shown.png differ diff --git a/DSView/icons/light/single.png b/DSView/icons/light/single.png new file mode 100755 index 0000000000000000000000000000000000000000..48862af49ff462329814cbbeb63731b3fffa72f1 Binary files /dev/null and b/DSView/icons/light/single.png differ diff --git a/DSView/icons/light/start.png b/DSView/icons/light/start.png new file mode 100755 index 0000000000000000000000000000000000000000..8f1b00531a562365be3980852de6d2203c294026 Binary files /dev/null and b/DSView/icons/light/start.png differ diff --git a/DSView/icons/light/stop.png b/DSView/icons/light/stop.png new file mode 100755 index 0000000000000000000000000000000000000000..7f2b01e56448af3b0019e730dfd031625a987e36 Binary files /dev/null and b/DSView/icons/light/stop.png differ diff --git a/DSView/icons/light/support.png b/DSView/icons/light/support.png new file mode 100755 index 0000000000000000000000000000000000000000..0c8abcb5f7915880b5b16d45d73ca841253e2af5 Binary files /dev/null and b/DSView/icons/light/support.png differ diff --git a/DSView/icons/light/trigger.png b/DSView/icons/light/trigger.png new file mode 100755 index 0000000000000000000000000000000000000000..83c1d1872b049ec06c7e63867e649b19b0d4a99a Binary files /dev/null and b/DSView/icons/light/trigger.png differ diff --git a/DSView/icons/light/wait.gif b/DSView/icons/light/wait.gif new file mode 100755 index 0000000000000000000000000000000000000000..97142aa2da7e7299a9bc1cb79e64068f2fffaadd Binary files /dev/null and b/DSView/icons/light/wait.gif differ diff --git a/DSView/icons/lissajous.png b/DSView/icons/lissajous.png new file mode 100755 index 0000000000000000000000000000000000000000..f767b6b614e68821962c9eeffe2c022d7a90dbfa Binary files /dev/null and b/DSView/icons/lissajous.png differ diff --git a/DSView/icons/load.gif b/DSView/icons/load.gif deleted file mode 100644 index ffcb5622b8c2d86b3eaf3d840a881edb8434e3d4..0000000000000000000000000000000000000000 Binary files a/DSView/icons/load.gif and /dev/null differ diff --git a/DSView/icons/logo.png b/DSView/icons/logo.png old mode 100644 new mode 100755 diff --git a/DSView/icons/logo.svg b/DSView/icons/logo.svg deleted file mode 100755 index b713c3045e9a61b61df594d5e6a0561711828574..0000000000000000000000000000000000000000 --- a/DSView/icons/logo.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/DSView/icons/logo_128.png b/DSView/icons/logo_128.png deleted file mode 100755 index 0d46a075e34e2644f08d9387589d41dad485f5a8..0000000000000000000000000000000000000000 Binary files a/DSView/icons/logo_128.png and /dev/null differ diff --git a/DSView/icons/logo_16.png b/DSView/icons/logo_16.png deleted file mode 100755 index 67042eb351714c83d8f85a59b47251a47faef19b..0000000000000000000000000000000000000000 Binary files a/DSView/icons/logo_16.png and /dev/null differ diff --git a/DSView/icons/logo_256.png b/DSView/icons/logo_256.png deleted file mode 100755 index ca65932dba42d47c3b34759ac84cf0302fcb5eb4..0000000000000000000000000000000000000000 Binary files a/DSView/icons/logo_256.png and /dev/null differ diff --git a/DSView/icons/logo_32.png b/DSView/icons/logo_32.png deleted file mode 100755 index ed7b1a4ea8849a0abc8fbb07be1447f3aa0d6436..0000000000000000000000000000000000000000 Binary files a/DSView/icons/logo_32.png and /dev/null differ diff --git a/DSView/icons/logo_48.png b/DSView/icons/logo_48.png deleted file mode 100755 index eb8b41628fe9ef3f10ff36a826e8e56b29de5ef6..0000000000000000000000000000000000000000 Binary files a/DSView/icons/logo_48.png and /dev/null differ diff --git a/DSView/icons/logo_64.png b/DSView/icons/logo_64.png deleted file mode 100755 index 8691e8903a40d8b6da71b99fbab4cfa6800bb5d1..0000000000000000000000000000000000000000 Binary files a/DSView/icons/logo_64.png and /dev/null differ diff --git a/DSView/icons/logo_color.png b/DSView/icons/logo_color.png deleted file mode 100755 index 0761dd75243d998014e4d7822092b13f6483db50..0000000000000000000000000000000000000000 Binary files a/DSView/icons/logo_color.png and /dev/null differ diff --git a/DSView/icons/logo_noColor.png b/DSView/icons/logo_noColor.png deleted file mode 100755 index a532a178c317ef52a724f6256c7d9f5b41dc2aa7..0000000000000000000000000000000000000000 Binary files a/DSView/icons/logo_noColor.png and /dev/null differ diff --git a/DSView/icons/mAmplitude.png b/DSView/icons/mAmplitude.png new file mode 100755 index 0000000000000000000000000000000000000000..68814aa7f1c7b5ecda4e15114adc122f9ff1f1ce Binary files /dev/null and b/DSView/icons/mAmplitude.png differ diff --git a/DSView/icons/mBurst.png b/DSView/icons/mBurst.png new file mode 100755 index 0000000000000000000000000000000000000000..cb449f9c9e85658fca695ae6a0b33fb08de99d40 Binary files /dev/null and b/DSView/icons/mBurst.png differ diff --git a/DSView/icons/mDelay.png b/DSView/icons/mDelay.png new file mode 100755 index 0000000000000000000000000000000000000000..1a992d1ad7e50b12273d0fb04f8dda8f2d6f1af7 Binary files /dev/null and b/DSView/icons/mDelay.png differ diff --git a/DSView/icons/mFall.png b/DSView/icons/mFall.png new file mode 100755 index 0000000000000000000000000000000000000000..1b2a9ac3ad5d8703fe7cc8ef448c8cfd93e91b0c Binary files /dev/null and b/DSView/icons/mFall.png differ diff --git a/DSView/icons/mFreq.png b/DSView/icons/mFreq.png new file mode 100755 index 0000000000000000000000000000000000000000..ed8ccf14a56bab9550d49d9253acd482db569ce1 Binary files /dev/null and b/DSView/icons/mFreq.png differ diff --git a/DSView/icons/mHigh.png b/DSView/icons/mHigh.png new file mode 100755 index 0000000000000000000000000000000000000000..665d4c0c376ec9a68efb1db1951d73f590eec5d9 Binary files /dev/null and b/DSView/icons/mHigh.png differ diff --git a/DSView/icons/mLow.png b/DSView/icons/mLow.png new file mode 100755 index 0000000000000000000000000000000000000000..779a0e16192a03a7fc1aab05f54a59da625ef26e Binary files /dev/null and b/DSView/icons/mLow.png differ diff --git a/DSView/icons/mMax.png b/DSView/icons/mMax.png new file mode 100755 index 0000000000000000000000000000000000000000..36572e3a39cc297335c78ad6a364a806a12a9532 Binary files /dev/null and b/DSView/icons/mMax.png differ diff --git a/DSView/icons/mMean.png b/DSView/icons/mMean.png new file mode 100755 index 0000000000000000000000000000000000000000..a65dd0980b3ae46fab919d608784a5176c4f31e9 Binary files /dev/null and b/DSView/icons/mMean.png differ diff --git a/DSView/icons/mMin.png b/DSView/icons/mMin.png new file mode 100755 index 0000000000000000000000000000000000000000..b9779a23638f740d83b510f4597cc30350c2c9f2 Binary files /dev/null and b/DSView/icons/mMin.png differ diff --git a/DSView/icons/mNduty.png b/DSView/icons/mNduty.png new file mode 100755 index 0000000000000000000000000000000000000000..fb2ea68e03b76dd41ae1be0939f5af7c98ff9a2a Binary files /dev/null and b/DSView/icons/mNduty.png differ diff --git a/DSView/icons/mNover.png b/DSView/icons/mNover.png new file mode 100755 index 0000000000000000000000000000000000000000..80342c5967cc037b791914ccd35c241c18be1c47 Binary files /dev/null and b/DSView/icons/mNover.png differ diff --git a/DSView/icons/mNwidth.png b/DSView/icons/mNwidth.png new file mode 100755 index 0000000000000000000000000000000000000000..52782332d3144d9d2c1cd4802f1a56e0e65b1eb0 Binary files /dev/null and b/DSView/icons/mNwidth.png differ diff --git a/DSView/icons/mPcount.png b/DSView/icons/mPcount.png new file mode 100755 index 0000000000000000000000000000000000000000..eab790723cfa772054a69364c39140862fe47459 Binary files /dev/null and b/DSView/icons/mPcount.png differ diff --git a/DSView/icons/mPduty.png b/DSView/icons/mPduty.png new file mode 100755 index 0000000000000000000000000000000000000000..ab4a48d3e961fd1d3a311b67a7c9b749462170c5 Binary files /dev/null and b/DSView/icons/mPduty.png differ diff --git a/DSView/icons/mPeriod.png b/DSView/icons/mPeriod.png new file mode 100755 index 0000000000000000000000000000000000000000..d7722656b5ce69e9894f415e4244f52a9f8f1a09 Binary files /dev/null and b/DSView/icons/mPeriod.png differ diff --git a/DSView/icons/mPover.png b/DSView/icons/mPover.png new file mode 100755 index 0000000000000000000000000000000000000000..d7077a8febcaebba754df1c51af372c5f7864c58 Binary files /dev/null and b/DSView/icons/mPover.png differ diff --git a/DSView/icons/mPwidth.png b/DSView/icons/mPwidth.png new file mode 100755 index 0000000000000000000000000000000000000000..1bd4c4b3a576443dcb93ad46eef802b6670bff65 Binary files /dev/null and b/DSView/icons/mPwidth.png differ diff --git a/DSView/icons/mRise.png b/DSView/icons/mRise.png new file mode 100755 index 0000000000000000000000000000000000000000..69eef45fa4e85b80fb49d6a866f30f505f88e046 Binary files /dev/null and b/DSView/icons/mRise.png differ diff --git a/DSView/icons/mRms.png b/DSView/icons/mRms.png new file mode 100755 index 0000000000000000000000000000000000000000..a44db72764f553ac1ee0eb14bf8c1b20a0023dae Binary files /dev/null and b/DSView/icons/mRms.png differ diff --git a/DSView/icons/mVpp.png b/DSView/icons/mVpp.png new file mode 100755 index 0000000000000000000000000000000000000000..4c42d1a3a80432f5c3e612ee05f151273c9706de Binary files /dev/null and b/DSView/icons/mVpp.png differ diff --git a/DSView/icons/math.png b/DSView/icons/math.png old mode 100644 new mode 100755 index dbb83a78fec272e7b6a5b1b20f0431491b6a66af..a468dc6a166540339b6e04d21f2d42569707aaa5 Binary files a/DSView/icons/math.png and b/DSView/icons/math.png differ diff --git a/DSView/icons/math_dis.png b/DSView/icons/math_dis.png deleted file mode 100644 index 9850dd5e09f1ac5da0cd70726cc86e942c89cc38..0000000000000000000000000000000000000000 Binary files a/DSView/icons/math_dis.png and /dev/null differ diff --git a/DSView/icons/maximize.png b/DSView/icons/maximize.png deleted file mode 100644 index bb4bffb855e02052ad8655447158c97c2fae48fd..0000000000000000000000000000000000000000 Binary files a/DSView/icons/maximize.png and /dev/null differ diff --git a/DSView/icons/measure.png b/DSView/icons/measure.png deleted file mode 100644 index 461bb7c99808d5a89e4d115bcff04f829bc77daa..0000000000000000000000000000000000000000 Binary files a/DSView/icons/measure.png and /dev/null differ diff --git a/DSView/icons/measure_dis.png b/DSView/icons/measure_dis.png deleted file mode 100644 index 3f152eee474dd2a7e85cbf21166381409004c8d9..0000000000000000000000000000000000000000 Binary files a/DSView/icons/measure_dis.png and /dev/null differ diff --git a/DSView/icons/minimize.png b/DSView/icons/minimize.png deleted file mode 100644 index 7c9a9fd3e0899a367b7e4a1c71481a0499e10d7b..0000000000000000000000000000000000000000 Binary files a/DSView/icons/minimize.png and /dev/null differ diff --git a/DSView/icons/moder.png b/DSView/icons/moder.png deleted file mode 100755 index d94f826a75321345566e1513bba0eb6e17b7eed8..0000000000000000000000000000000000000000 Binary files a/DSView/icons/moder.png and /dev/null differ diff --git a/DSView/icons/moder_dis.png b/DSView/icons/moder_dis.png deleted file mode 100755 index 8bc447215db1bf8ff2b8d4614f61ca88f38acb07..0000000000000000000000000000000000000000 Binary files a/DSView/icons/moder_dis.png and /dev/null differ diff --git a/DSView/icons/modes.png b/DSView/icons/modes.png deleted file mode 100755 index c8e465ceb7b8e1864e096e8bdd45d9aa09ec062b..0000000000000000000000000000000000000000 Binary files a/DSView/icons/modes.png and /dev/null differ diff --git a/DSView/icons/modes_dis.png b/DSView/icons/modes_dis.png deleted file mode 100755 index 375a2a509dc81301caa746bfd05c54498b34e199..0000000000000000000000000000000000000000 Binary files a/DSView/icons/modes_dis.png and /dev/null differ diff --git a/DSView/icons/params.png b/DSView/icons/params.png deleted file mode 100644 index d6a9fff7e00b5d973b0859be97ddc3fa2fba6ed3..0000000000000000000000000000000000000000 Binary files a/DSView/icons/params.png and /dev/null differ diff --git a/DSView/icons/params_dis.png b/DSView/icons/params_dis.png deleted file mode 100644 index af2518a79d3016b5e09083dee660d0d91d47e994..0000000000000000000000000000000000000000 Binary files a/DSView/icons/params_dis.png and /dev/null differ diff --git a/DSView/icons/protocol.png b/DSView/icons/protocol.png deleted file mode 100644 index acf434e2f3c3dd55e53709aaf3ee9080d72308fc..0000000000000000000000000000000000000000 Binary files a/DSView/icons/protocol.png and /dev/null differ diff --git a/DSView/icons/protocol_dis.png b/DSView/icons/protocol_dis.png deleted file mode 100644 index 3836866f0769ed16e48aa236c50a4b08ec39e6e6..0000000000000000000000000000000000000000 Binary files a/DSView/icons/protocol_dis.png and /dev/null differ diff --git a/DSView/icons/restore.png b/DSView/icons/restore.png deleted file mode 100644 index ceaa6235a050f53d3828477e6cb885cd34148c29..0000000000000000000000000000000000000000 Binary files a/DSView/icons/restore.png and /dev/null differ diff --git a/DSView/icons/search-bar.png b/DSView/icons/search-bar.png deleted file mode 100644 index 1e58096d44e309e6efab825b0200958c308c0f66..0000000000000000000000000000000000000000 Binary files a/DSView/icons/search-bar.png and /dev/null differ diff --git a/DSView/icons/search-bar_dis.png b/DSView/icons/search-bar_dis.png deleted file mode 100644 index 1b2d6955dd5e18ac6a6d65ff378f5c1c238ec7b3..0000000000000000000000000000000000000000 Binary files a/DSView/icons/search-bar_dis.png and /dev/null differ diff --git a/DSView/icons/search.png b/DSView/icons/search.png old mode 100644 new mode 100755 diff --git a/DSView/icons/settings.png b/DSView/icons/settings.png deleted file mode 100644 index b0065b510a7b42f26f5cece13c439feef66091a4..0000000000000000000000000000000000000000 Binary files a/DSView/icons/settings.png and /dev/null differ diff --git a/DSView/icons/showDoc.png b/DSView/icons/showDoc.png deleted file mode 100755 index 7a306d110a9f760c8b1b8c9c01b59045a354a12d..0000000000000000000000000000000000000000 Binary files a/DSView/icons/showDoc.png and /dev/null differ diff --git a/DSView/icons/showDoc25.png b/DSView/icons/showDoc25.png new file mode 100755 index 0000000000000000000000000000000000000000..c1ea34c40e4e0ac193ca2f214ad41c808dc25570 Binary files /dev/null and b/DSView/icons/showDoc25.png differ diff --git a/DSView/icons/showDoc31.png b/DSView/icons/showDoc31.png new file mode 100755 index 0000000000000000000000000000000000000000..0bbfebeb174c1f1b339e59d20086d996270e818e Binary files /dev/null and b/DSView/icons/showDoc31.png differ diff --git a/DSView/icons/single.png b/DSView/icons/single.png deleted file mode 100644 index c0565af0449c936b4e0e6cb575004112efdeec9c..0000000000000000000000000000000000000000 Binary files a/DSView/icons/single.png and /dev/null differ diff --git a/DSView/icons/single_dis.png b/DSView/icons/single_dis.png deleted file mode 100644 index 4e1221f83739bd06294778e61b0f596b17d90473..0000000000000000000000000000000000000000 Binary files a/DSView/icons/single_dis.png and /dev/null differ diff --git a/DSView/icons/slider-handle.png b/DSView/icons/slider-handle.png deleted file mode 100644 index ac1f6e22cc975c9c462ac86c8de49a56c72c80b1..0000000000000000000000000000000000000000 Binary files a/DSView/icons/slider-handle.png and /dev/null differ diff --git a/DSView/icons/start.png b/DSView/icons/start.png deleted file mode 100644 index 4c2d7e611bdf1f57704ce7f9f80499288125493c..0000000000000000000000000000000000000000 Binary files a/DSView/icons/start.png and /dev/null differ diff --git a/DSView/icons/start_dis.png b/DSView/icons/start_dis.png deleted file mode 100644 index 56f6e90117665371851f3fe421852cac938698eb..0000000000000000000000000000000000000000 Binary files a/DSView/icons/start_dis.png and /dev/null differ diff --git a/DSView/icons/stop.png b/DSView/icons/stop.png deleted file mode 100644 index 77aa105d9f535a2f89d6aafb65464da8b78cc45e..0000000000000000000000000000000000000000 Binary files a/DSView/icons/stop.png and /dev/null differ diff --git a/DSView/icons/trigger.png b/DSView/icons/trigger.png deleted file mode 100644 index 6b1ca1b8e3bd865f2d0d50a2e64a25bdc05d909e..0000000000000000000000000000000000000000 Binary files a/DSView/icons/trigger.png and /dev/null differ diff --git a/DSView/icons/trigger_dis.png b/DSView/icons/trigger_dis.png deleted file mode 100644 index eb401cff315562160b57869f5f18811b853cac56..0000000000000000000000000000000000000000 Binary files a/DSView/icons/trigger_dis.png and /dev/null differ diff --git a/DSView/icons/wait.gif b/DSView/icons/wait.gif deleted file mode 100644 index b3ba36a619d15ef20c1e7f5087fcfcef2ea452f9..0000000000000000000000000000000000000000 Binary files a/DSView/icons/wait.gif and /dev/null differ diff --git a/DSView/languages/language.qrc b/DSView/languages/language.qrc new file mode 100755 index 0000000000000000000000000000000000000000..e0eacdf859074171a2ec3bcae89543e90d30f345 --- /dev/null +++ b/DSView/languages/language.qrc @@ -0,0 +1,6 @@ + + + my_25.qm + qt_25.qm + + diff --git a/DSView/languages/my_25.qm b/DSView/languages/my_25.qm new file mode 100755 index 0000000000000000000000000000000000000000..2430370fea5fdfd37b1dc4487c6df93ed087dea3 Binary files /dev/null and b/DSView/languages/my_25.qm differ diff --git a/DSView/languages/qt_25.qm b/DSView/languages/qt_25.qm new file mode 100755 index 0000000000000000000000000000000000000000..3e5c146b14e0e5bd643a55a9f4fa625c547ad2b0 Binary files /dev/null and b/DSView/languages/qt_25.qm differ diff --git a/DSView/main.cpp b/DSView/main.cpp old mode 100644 new mode 100755 index e8157ff5e14103866ad3330acddf50039cfe694b..7350d34f390a40ccbbc59c48d15374a6fa2a1673 --- a/DSView/main.cpp +++ b/DSView/main.cpp @@ -63,12 +63,15 @@ int main(int argc, char *argv[]) struct sr_context *sr_ctx = NULL; const char *open_file = NULL; + QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QApplication a(argc, argv); // Set some application metadata QApplication::setApplicationVersion(DS_VERSION_STRING); QApplication::setApplicationName("DSView"); - QApplication::setOrganizationDomain("http://www.DreamSourceLab.com"); + QApplication::setOrganizationName("DreamSourceLab"); + QApplication::setOrganizationDomain("www.DreamSourceLab.com"); // Parse arguments while (1) { @@ -115,7 +118,7 @@ int main(int argc, char *argv[]) } else if (argc - optind == 1) open_file = argv[argc - 1]; - // Initialise DS_RES_PATH + // Initialise DS_RES_PATH QDir dir(QCoreApplication::applicationDirPath()); if (dir.cd("..") && dir.cd("share") && @@ -153,11 +156,6 @@ int main(int argc, char *argv[]) // Initialise the main frame pv::MainFrame w(device_manager, open_file); - //QFile qss(":/stylesheet.qss"); - QFile qss(":darkstyle/style.qss"); - qss.open(QFile::ReadOnly); - a.setStyleSheet(qss.readAll()); - qss.close(); w.show(); w.readSettings(); w.show_doc(); diff --git a/DSView/pv/data/analog.cpp b/DSView/pv/data/analog.cpp old mode 100644 new mode 100755 diff --git a/DSView/pv/data/analog.h b/DSView/pv/data/analog.h old mode 100644 new mode 100755 diff --git a/DSView/pv/data/analogsnapshot.cpp b/DSView/pv/data/analogsnapshot.cpp old mode 100644 new mode 100755 index bd73ae91190dac1a820f2c1556048ec4cab25e1a..91e11e6d2465a29f2216309d8eb48bf1c7449691 --- a/DSView/pv/data/analogsnapshot.cpp +++ b/DSView/pv/data/analogsnapshot.cpp @@ -123,18 +123,16 @@ void AnalogSnapshot::first_payload(const sr_datafeed_analog &analog, uint64_t to for (unsigned int i = 0; i < _channel_num; i++) { uint64_t envelop_count = _total_sample_count / EnvelopeScaleFactor; for (unsigned int level = 0; level < ScaleStepCount; level++) { - envelop_count = ((envelop_count + EnvelopeDataUnit - 1) / - EnvelopeDataUnit) * EnvelopeDataUnit; +// envelop_count = ((envelop_count + EnvelopeDataUnit - 1) / +// EnvelopeDataUnit) * EnvelopeDataUnit; + _envelope_levels[i][level].count = envelop_count; + if (envelop_count == 0) + break; _envelope_levels[i][level].samples = (EnvelopeSample*)malloc(envelop_count * sizeof(EnvelopeSample)); - _envelope_levels[i][level].max = (uint8_t *)malloc(envelop_count * _unit_bytes); - _envelope_levels[i][level].min = (uint8_t *)malloc(envelop_count * _unit_bytes); - if (!_envelope_levels[i][level].samples || - !_envelope_levels[i][level].max || - !_envelope_levels[i][level].min) { + if (!_envelope_levels[i][level].samples) { isOk = false; break; } - _envelope_levels[i][level].count = envelop_count; envelop_count = envelop_count / EnvelopeScaleFactor; } if (!isOk) @@ -277,7 +275,7 @@ void AnalogSnapshot::append_payload_to_envelope_levels() if (e0.length == 0) continue; - reallocate_envelope(e0); + //reallocate_envelope(e0); dest_ptr = e0.samples + prev_length; @@ -324,13 +322,13 @@ void AnalogSnapshot::append_payload_to_envelope_levels() if (e.ring_length == prev_length) break; - reallocate_envelope(e); + //reallocate_envelope(e); // Subsample the level lower level const EnvelopeSample *src_ptr = el.samples + prev_length * EnvelopeScaleFactor; - const EnvelopeSample *const end_dest_ptr = e.samples + e.ring_length; - dest_ptr = e.samples + prev_length; + const EnvelopeSample *const end_dest_ptr = (e.ring_length == e.count) ? e.samples : e.samples + e.ring_length; + dest_ptr = (prev_length == e.count) ? e.samples : e.samples + prev_length; while(dest_ptr != end_dest_ptr) { const EnvelopeSample * end_src_ptr = src_ptr + EnvelopeScaleFactor; diff --git a/DSView/pv/data/analogsnapshot.h b/DSView/pv/data/analogsnapshot.h old mode 100644 new mode 100755 index 25d1c0d6256d909212a77e5df3c8deaac8364878..644dbfaa0bfc768933ca811054bee5e34a6875da --- a/DSView/pv/data/analogsnapshot.h +++ b/DSView/pv/data/analogsnapshot.h @@ -54,8 +54,6 @@ public: uint64_t length; uint64_t samples_num; EnvelopeSample *samples; - uint8_t *max; - uint8_t *min; }; private: diff --git a/DSView/pv/data/decode/annotation.cpp b/DSView/pv/data/decode/annotation.cpp old mode 100644 new mode 100755 index 3581817d11b49a29f7390c7d6939af7bbc382c34..c433a2883d412a6678b749e59b4b9f76a1a044a3 --- a/DSView/pv/data/decode/annotation.cpp +++ b/DSView/pv/data/decode/annotation.cpp @@ -45,7 +45,7 @@ Annotation::Annotation(const srd_proto_data *const pdata) : _type = pda->ann_type; const char *const *annotations = (char**)pda->ann_text; - while(*annotations) { + while(*annotations) { _annotations.push_back(QString::fromUtf8(*annotations)); annotations++; } diff --git a/DSView/pv/data/decode/annotation.h b/DSView/pv/data/decode/annotation.h old mode 100644 new mode 100755 diff --git a/DSView/pv/data/decode/decoder.cpp b/DSView/pv/data/decode/decoder.cpp old mode 100644 new mode 100755 index fed10d7714511e1e3c7b6fa12ed5c632ef966f1c..486340cc020a09a137d02f7a4fe062526b31bf7e --- a/DSView/pv/data/decode/decoder.cpp +++ b/DSView/pv/data/decode/decoder.cpp @@ -43,7 +43,8 @@ Decoder::~Decoder() { for (map::const_iterator i = _options_back.begin(); i != _options_back.end(); i++) - g_variant_unref((*i).second); + if ((*i).second) + g_variant_unref((*i).second); } const srd_decoder* Decoder::decoder() const @@ -81,7 +82,9 @@ const std::map& Decoder::options() const void Decoder::set_option(const char *id, GVariant *value) { assert(value); - g_variant_unref(_options_back[id]); + if (_options_back[id]) { + g_variant_unref(_options_back[id]); + } g_variant_ref(value); _options_back[id] = value; _setted = true; diff --git a/DSView/pv/data/decode/decoder.h b/DSView/pv/data/decode/decoder.h old mode 100644 new mode 100755 diff --git a/DSView/pv/data/decode/row.cpp b/DSView/pv/data/decode/row.cpp old mode 100644 new mode 100755 diff --git a/DSView/pv/data/decode/row.h b/DSView/pv/data/decode/row.h old mode 100644 new mode 100755 diff --git a/DSView/pv/data/decode/rowdata.cpp b/DSView/pv/data/decode/rowdata.cpp old mode 100644 new mode 100755 diff --git a/DSView/pv/data/decode/rowdata.h b/DSView/pv/data/decode/rowdata.h old mode 100644 new mode 100755 diff --git a/DSView/pv/data/decodermodel.cpp b/DSView/pv/data/decodermodel.cpp old mode 100644 new mode 100755 diff --git a/DSView/pv/data/decodermodel.h b/DSView/pv/data/decodermodel.h old mode 100644 new mode 100755 diff --git a/DSView/pv/data/decoderstack.cpp b/DSView/pv/data/decoderstack.cpp old mode 100644 new mode 100755 index 8e6a80396d4a116b8af186334db84f998e6dff8a..61a66dac8d8114fe582ef46a0aed52e6f647a7d7 --- a/DSView/pv/data/decoderstack.cpp +++ b/DSView/pv/data/decoderstack.cpp @@ -478,7 +478,6 @@ void DecoderStack::decode_data( } uint64_t entry_cnt = 0; - uint8_t chunk_type = 0; uint64_t i = decode_start; char *error = NULL; while(!boost::this_thread::interruption_requested() && @@ -492,6 +491,7 @@ void DecoderStack::decode_data( int sig_index = logic_di->dec_channelmap[j]; if (sig_index == -1) { chunk.push_back(NULL); + chunk_const.push_back(0); } else { if (_snapshot->has_data(sig_index)) { chunk.push_back(_snapshot->get_samples(i, chunk_end, sig_index)); @@ -502,57 +502,17 @@ void DecoderStack::decode_data( } } } + if (chunk_end > decode_end) + chunk_end = decode_end; if (chunk_end - i > MaxChunkSize) chunk_end = i + MaxChunkSize; - if (srd_session_send(session, chunk_type, i, chunk_end, - chunk.data(), chunk_const.data(), &error) != SRD_OK) { + if (srd_session_send(session, i, chunk_end, + chunk.data(), chunk_const.data(), chunk_end - i, &error) != SRD_OK) { _error_message = QString::fromLocal8Bit(error); break; } - - if (logic_di && logic_di->logic_mask != 0 && logic_di->cur_pos < decode_end) { - uint64_t cur_pos = logic_di->cur_pos; - uint64_t sample; - if (logic_di->edge_index == -1) { - std::vector pos_vector; - cur_pos++; - for (int j =0 ; j < logic_di->dec_num_channels; j++) { - int index = logic_di->dec_channelmap[j]; - if (index != -1 && (logic_di->logic_mask & (1 << j))) { - bool last_sample = _snapshot->get_sample(cur_pos - 1, index); - pos_vector.push_back(cur_pos); - _snapshot->get_nxt_edge(pos_vector.back(), last_sample, decode_end, 1, index); - } - } - cur_pos = *std::min_element(pos_vector.begin(), pos_vector.end()); - } else { - bool last_sample = _snapshot->get_sample(cur_pos, logic_di->edge_index); - do { - sample = 0; - cur_pos++; - if (!_snapshot->get_nxt_edge(cur_pos, last_sample, decode_end, 1, logic_di->edge_index)) - break; - for (int j =0 ; j < logic_di->dec_num_channels; j++) { - if (logic_di->logic_mask & (1 << j)) { - int index = logic_di->dec_channelmap[j]; - bool index_sample = _snapshot->get_sample(cur_pos, index); - sample += index_sample << j; - if (index == logic_di->edge_index) - last_sample = index_sample; - } - } - } while(sample != logic_di->exp_logic); - } - - i = cur_pos; - if (i >= decode_end) - i = decode_end; - chunk_type = 0; - } else { - i = chunk_end + 1; - chunk_type = 1; - } + i = chunk_end; { boost::lock_guard lock(_output_mutex); diff --git a/DSView/pv/data/decoderstack.h b/DSView/pv/data/decoderstack.h old mode 100644 new mode 100755 diff --git a/DSView/pv/data/dso.cpp b/DSView/pv/data/dso.cpp old mode 100644 new mode 100755 diff --git a/DSView/pv/data/dso.h b/DSView/pv/data/dso.h old mode 100644 new mode 100755 diff --git a/DSView/pv/data/dsosnapshot.cpp b/DSView/pv/data/dsosnapshot.cpp old mode 100644 new mode 100755 index f90b8e71d9236d5492568376f6d9983cfcd3f1fd..ae576be246cdb27ed09806e269f4b1b5d9a09f9d --- a/DSView/pv/data/dsosnapshot.cpp +++ b/DSView/pv/data/dsosnapshot.cpp @@ -163,16 +163,20 @@ void DsoSnapshot::append_payload(const sr_datafeed_dso &dso) append_data(dso.data, dso.num_samples, _instant); // Generate the first mip-map from the data + //if (_envelope_en) + // append_payload_to_envelope_levels(dso.samplerate_tog); if (_envelope_en) - append_payload_to_envelope_levels(dso.samplerate_tog); + append_payload_to_envelope_levels(true); } } void DsoSnapshot::append_data(void *data, uint64_t samples, bool instant) { if (instant) { + if(_sample_count + samples > _total_sample_count) + samples = _total_sample_count - _sample_count; memcpy((uint8_t*)_data + _sample_count * _channel_num, data, samples*_channel_num); - _sample_count = (_sample_count + samples) % (_total_sample_count + 1); + _sample_count += samples; } else { memcpy((uint8_t*)_data, data, samples*_channel_num); _sample_count = samples; @@ -304,12 +308,17 @@ void DsoSnapshot::append_payload_to_envelope_levels(bool header) const Envelope &el = _envelope_levels[i][level-1]; // Expand the data buffer to fit the new samples - prev_length = e.length; + if (header) + prev_length = 0; + else + prev_length = e.length; e.length = el.length / EnvelopeScaleFactor; // Break off if there are no more samples to computed // if (e.length == prev_length) // break; + if (e.length == 0) + break; if (e.length == prev_length) prev_length = 0; diff --git a/DSView/pv/data/dsosnapshot.h b/DSView/pv/data/dsosnapshot.h old mode 100644 new mode 100755 index 7b56c47aa63c197dacbacf7cb0e041f445795bc9..aa19cca56db7656448ef2d199377dd2130115b35 --- a/DSView/pv/data/dsosnapshot.h +++ b/DSView/pv/data/dsosnapshot.h @@ -82,7 +82,8 @@ public: void clear(); void init(); - void first_payload(const sr_datafeed_dso &dso, uint64_t total_sample_count, std::map ch_enable, bool instant); + void first_payload(const sr_datafeed_dso &dso, uint64_t total_sample_count, + std::map ch_enable, bool instant); void append_payload(const sr_datafeed_dso &dso); diff --git a/DSView/pv/data/group.cpp b/DSView/pv/data/group.cpp old mode 100644 new mode 100755 diff --git a/DSView/pv/data/group.h b/DSView/pv/data/group.h old mode 100644 new mode 100755 diff --git a/DSView/pv/data/groupsnapshot.cpp b/DSView/pv/data/groupsnapshot.cpp old mode 100644 new mode 100755 diff --git a/DSView/pv/data/groupsnapshot.h b/DSView/pv/data/groupsnapshot.h old mode 100644 new mode 100755 diff --git a/DSView/pv/data/logic.cpp b/DSView/pv/data/logic.cpp old mode 100644 new mode 100755 diff --git a/DSView/pv/data/logic.h b/DSView/pv/data/logic.h old mode 100644 new mode 100755 diff --git a/DSView/pv/data/logicsnapshot.cpp b/DSView/pv/data/logicsnapshot.cpp old mode 100644 new mode 100755 index d0cfec73390aee333b6f91a68a9cd40431b7d7b7..0542672259cde7d52cdc61cfb47681ab234a6764 --- a/DSView/pv/data/logicsnapshot.cpp +++ b/DSView/pv/data/logicsnapshot.cpp @@ -222,11 +222,14 @@ void LogicSnapshot::append_cross_payload( _src_ptr = logic.data; uint64_t len = logic.length; + // samples not accurate, lead to a larger _sampole_count + // _sample_count should be fixed in the last packet + // so _total_sample_count must be align to LeafBlock uint64_t samples = ceil(logic.length * 8.0 / _channel_num); if (_sample_count + samples < _total_sample_count) { _sample_count += samples; } else { - len = ceil((_total_sample_count - _sample_count) * _channel_num / 8.0); + //len = ceil((_total_sample_count - _sample_count) * _channel_num / 8.0); _sample_count = _total_sample_count; } @@ -471,7 +474,7 @@ const uint8_t *LogicSnapshot::get_samples(uint64_t start_sample, uint64_t &end_s { //assert(data); assert(start_sample < get_sample_count()); - assert(end_sample < get_sample_count()); + assert(end_sample <= get_sample_count()); assert(start_sample <= end_sample); int order = get_ch_order(sig_index); @@ -481,7 +484,7 @@ const uint8_t *LogicSnapshot::get_samples(uint64_t start_sample, uint64_t &end_s end_sample = (root_index << (LeafBlockPower + RootScalePower)) + (root_pos << LeafBlockPower) + ~(~0ULL << LeafBlockPower); - end_sample = min(end_sample, get_sample_count() - 1); + end_sample = min(end_sample + 1, get_sample_count()); if (order == -1 || _ch_data[order][root_index].lbp[root_pos] == NULL) diff --git a/DSView/pv/data/logicsnapshot.h b/DSView/pv/data/logicsnapshot.h old mode 100644 new mode 100755 diff --git a/DSView/pv/data/mathstack.cpp b/DSView/pv/data/mathstack.cpp old mode 100644 new mode 100755 index e33df5e84fba91d2b805c8688a65b736766f874a..5b9ce7a30d0de86a1e408214dccc4f3a40799f6b --- a/DSView/pv/data/mathstack.cpp +++ b/DSView/pv/data/mathstack.cpp @@ -36,39 +36,75 @@ using namespace std; namespace pv { namespace data { -const QString MathStack::windows_support[5] = { - QT_TR_NOOP("Rectangle"), - QT_TR_NOOP("Hann"), - QT_TR_NOOP("Hamming"), - QT_TR_NOOP("Blackman"), - QT_TR_NOOP("Flat_top") +const int MathStack::EnvelopeScalePower = 8; +const int MathStack::EnvelopeScaleFactor = 1 << EnvelopeScalePower; +const float MathStack::LogEnvelopeScaleFactor = logf(EnvelopeScaleFactor); +const uint64_t MathStack::EnvelopeDataUnit = 4*1024; // bytes + +const uint64_t MathStack::vDialValue[MathStack::vDialValueCount] = { + 1, + 2, + 5, + 10, + 20, + 50, + 100, + 200, + 500, + 1000, + 2000, + 5000, + 10000, + 20000, + 50000, + 100000, + 200000, + 500000, + 1000000, }; - -const uint64_t MathStack::length_support[5] = { - 1024, - 2048, - 4096, - 8192, - 16384, +const QString MathStack::vDialAddUnit[MathStack::vDialUnitCount] = { + "mV", + "V", +}; +const QString MathStack::vDialMulUnit[MathStack::vDialUnitCount] = { + "mV*V", + "V*V", +}; +const QString MathStack::vDialDivUnit[MathStack::vDialUnitCount] = { + "mV/V", + "V/V", }; -MathStack::MathStack(pv::SigSession &session, int index) : +MathStack::MathStack(pv::SigSession &session, + boost::shared_ptr dsoSig1, + boost::shared_ptr dsoSig2, + MathType type) : _session(session), - _index(index), - _dc_ignore(true), - _sample_interval(1), + _dsoSig1(dsoSig1), + _dsoSig2(dsoSig2), + _type(type), + _sample_num(0), + _total_sample_num(0), _math_state(Init), - _fft_plan(NULL) + _envelope_en(false), + _envelope_done(false) { + memset(_envelope_level, 0, sizeof(_envelope_level)); } MathStack::~MathStack() { - _xn.clear(); - _xk.clear(); - _power_spectrum.clear(); - if (_fft_plan) - fftw_destroy_plan(_fft_plan); + _math.clear(); + free_envelop(); +} + +void MathStack::free_envelop() +{ + BOOST_FOREACH(Envelope &e, _envelope_level) { + if (e.samples) + free(e.samples); + } + memset(_envelope_level, 0, sizeof(_envelope_level)); } void MathStack::clear() @@ -77,11 +113,13 @@ void MathStack::clear() void MathStack::init() { + _sample_num = 0; + _envelope_done = false; } -int MathStack::get_index() const +MathStack::MathType MathStack::get_type() const { - return _index; + return _type; } uint64_t MathStack::get_sample_num() const @@ -89,158 +127,351 @@ uint64_t MathStack::get_sample_num() const return _sample_num; } -void MathStack::set_sample_num(uint64_t num) +void MathStack::realloc(uint64_t num) { - _sample_num = num; - _xn.resize(_sample_num); - _xk.resize(_sample_num); - _power_spectrum.resize(_sample_num/2+1); - _fft_plan = fftw_plan_r2r_1d(_sample_num, _xn.data(), _xk.data(), - FFTW_R2HC, FFTW_ESTIMATE); + if (num != _total_sample_num) { + free_envelop(); + _total_sample_num = num; + + _math.resize(_total_sample_num); + uint64_t envelop_count = _total_sample_num / EnvelopeScaleFactor; + for (unsigned int level = 0; level < ScaleStepCount; level++) { + envelop_count = ((envelop_count + EnvelopeDataUnit - 1) / + EnvelopeDataUnit) * EnvelopeDataUnit; + _envelope_level[level].samples = (EnvelopeSample*)malloc(envelop_count * sizeof(EnvelopeSample)); + envelop_count = envelop_count / EnvelopeScaleFactor; + } + } } -int MathStack::get_windows_index() const +void MathStack::enable_envelope(bool enable) { - return _windows_index; + if (!_envelope_done && enable) + append_to_envelope_level(true); + _envelope_en = enable; } -void MathStack::set_windows_index(int index) +uint64_t MathStack::default_vDialValue() { - _windows_index = index; -} + uint64_t value = 0; + view::dslDial *dial1 = _dsoSig1->get_vDial(); + view::dslDial *dial2 = _dsoSig1->get_vDial(); + const uint64_t dial1_value = dial1->get_value() * dial1->get_factor(); + const uint64_t dial2_value = dial2->get_value() * dial2->get_factor(); + + switch(_type) { + case MATH_ADD: + case MATH_SUB: + value = max(dial1_value, dial2_value); + break; + case MATH_MUL: + value = dial1_value * dial2_value / 1000.0; + break; + case MATH_DIV: + value = dial1_value * 1000.0 / dial2_value; + break; + } -bool MathStack::dc_ignored() const -{ - return _dc_ignore; -} + for (int i = 0; i < vDialValueCount; i++) { + if (vDialValue[i] >= value) { + value = vDialValue[i]; + break; + } + } -void MathStack::set_dc_ignore(bool ignore) -{ - _dc_ignore = ignore; + return value; } -int MathStack::get_sample_interval() const +view::dslDial * MathStack::get_vDial() { - return _sample_interval; -} + QVector vValue; + QVector vUnit; + view::dslDial *dial1 = _dsoSig1->get_vDial(); + view::dslDial *dial2 = _dsoSig2->get_vDial(); + const uint64_t dial1_min = dial1->get_value(0) * dial1->get_factor(); + const uint64_t dial1_max = dial1->get_value(dial1->get_count() - 1) * dial1->get_factor(); + const uint64_t dial2_min = dial2->get_value(0) * dial2->get_factor(); + const uint64_t dial2_max = dial2->get_value(dial2->get_count() - 1) * dial2->get_factor(); + + switch(_type) { + case MATH_ADD: + case MATH_SUB: + for (int i = 0; i < vDialValueCount; i++) { + if (vDialValue[i] < min(dial1_min, dial2_min)) + continue; + vValue.append(vDialValue[i]); + if (vDialValue[i] > max(dial1_max, dial2_max)) + break; + } + for(int i = 0; i < vDialUnitCount; i++) + vUnit.append(vDialAddUnit[i]); + break; + case MATH_MUL: + for (int i = 0; i < vDialValueCount; i++) { + if (vDialValue[i] < dial1_min * dial2_min / 1000.0) + continue; + vValue.append(vDialValue[i]); + if (vDialValue[i] > dial1_max * dial2_max / 1000.0) + break; + } + for(int i = 0; i < vDialUnitCount; i++) + vUnit.append(vDialMulUnit[i]); + break; + case MATH_DIV: + for (int i = 0; i < vDialValueCount; i++) { + if (vDialValue[i] < min(dial1_min * 1000.0 / dial2_max, dial2_min * 1000.0 / dial1_max)) + continue; + vValue.append(vDialValue[i]); + if (vDialValue[i] > max(dial1_max * 1000.0 / dial2_min, dial2_max * 1000.0 / dial1_min)) + break; + } + for(int i = 0; i < vDialUnitCount; i++) + vUnit.append(vDialDivUnit[i]); + break; + } -void MathStack::set_sample_interval(int interval) -{ - _sample_interval = interval; + view::dslDial *vDial = new view::dslDial(vValue.count(), vDialValueStep, vValue, vUnit); + return vDial; } -const std::vector MathStack::get_windows_support() const +QString MathStack::get_unit(int level) { - std::vector windows; - for (size_t i = 0; i < sizeof(windows_support)/sizeof(windows_support[0]); i++) - { - windows.push_back(windows_support[i]); + if (level >= vDialUnitCount) + return tr(" "); + + QString unit; + switch(_type) { + case MATH_ADD: + case MATH_SUB: + unit = vDialAddUnit[level]; + break; + case MATH_MUL: + unit = vDialMulUnit[level]; + break; + case MATH_DIV: + unit = vDialDivUnit[level]; + break; } - return windows; + + return unit; } -const std::vector MathStack::get_length_support() const +double MathStack::get_math_scale() { - std::vector length; - for (size_t i = 0; i < sizeof(length_support)/sizeof(length_support[0]); i++) - { - length.push_back(length_support[i]); + double scale = 0; + switch(_type) { + case MATH_ADD: + case MATH_SUB: + scale = 1.0 / DS_CONF_DSO_VDIVS; + break; + case MATH_MUL: + //scale = 1.0 / (DS_CONF_DSO_VDIVS * DS_CONF_DSO_VDIVS); + scale = 1.0 / DS_CONF_DSO_VDIVS; + break; + case MATH_DIV: + scale = 1.0 / DS_CONF_DSO_VDIVS; + break; } - return length; + + return scale; } -const std::vector MathStack::get_fft_spectrum() const +const double* MathStack::get_math(uint64_t start) const { - std::vector empty; - if (_math_state == Stopped) - return _power_spectrum; - else - return empty; + return _math.data() + start; } -double MathStack::get_fft_spectrum(uint64_t index) +void MathStack::get_math_envelope_section(EnvelopeSection &s, + uint64_t start, uint64_t end, float min_length) const { - double ret = -1; - if (_math_state == Stopped && index < _power_spectrum.size()) - ret = _power_spectrum[index]; + assert(end <= get_sample_num()); + assert(start <= end); + assert(min_length > 0); + + if (!_envelope_done) { + s.length = 0; + return; + } + + const unsigned int min_level = max((int)floorf(logf(min_length) / + LogEnvelopeScaleFactor) - 1, 0); + const unsigned int scale_power = (min_level + 1) * + EnvelopeScalePower; + start >>= scale_power; + end >>= scale_power; + + s.start = start << scale_power; + s.scale = 1 << scale_power; + if (_envelope_level[min_level].length == 0) + s.length = 0; + else + s.length = end - start; - return ret; + s.samples = _envelope_level[min_level].samples + start; } -void MathStack::calc_fft() +void MathStack::calc_math() { _math_state = Running; - // Get the dso data - boost::shared_ptr data; - boost::shared_ptr dsoSig; - BOOST_FOREACH(const boost::shared_ptr s, _session.get_signals()) { - if ((dsoSig = dynamic_pointer_cast(s))) { - if (dsoSig->get_index() == _index && dsoSig->enabled()) { - data = dsoSig->dso_data(); - break; - } - } - } - if (!data) - return; - - // Check we have a snapshot of data + const boost::shared_ptr data = _dsoSig1->dso_data(); const deque< boost::shared_ptr > &snapshots = data->get_snapshots(); if (snapshots.empty()) return; - _snapshot = snapshots.front(); - if (_snapshot->get_sample_count() < _sample_num*_sample_interval) + const boost::shared_ptr &snapshot = + snapshots.front(); + if (snapshot->empty()) return; - // Get the samplerate - _samplerate = data->samplerate(); - if (_samplerate == 0.0) - _samplerate = 1.0; - - // prepare _xn data - const double offset = dsoSig->get_hw_offset(); - const double vscale = dsoSig->get_vDialValue() * dsoSig->get_factor() * DS_CONF_DSO_VDIVS / (1000*255.0); - const uint16_t step = _snapshot->get_channel_num() * _sample_interval; - const uint8_t *const samples = _snapshot->get_samples(0, _sample_num*_sample_interval-1, _index); - double wsum = 0; - for (unsigned int i = 0; i < _sample_num; i++) { - double w = window(i, _windows_index); - _xn[i] = ((double)samples[i*step] - offset) * vscale * w; - wsum += w; - } + if (_math.size() < _total_sample_num) + return; - // fft - fftw_execute(_fft_plan); + if (!_dsoSig1->enabled() || !_dsoSig2->enabled()) + return; - // calculate power spectrum - _power_spectrum[0] = abs(_xk[0])/wsum; /* DC component */ - for (unsigned int k = 1; k < (_sample_num + 1) / 2; ++k) /* (k < N/2 rounded up) */ - _power_spectrum[k] = sqrt((_xk[k]*_xk[k] + _xk[_sample_num-k]*_xk[_sample_num-k]) * 2) / wsum; - if (_sample_num % 2 == 0) /* N is even */ - _power_spectrum[_sample_num/2] = abs(_xk[_sample_num/2])/wsum; /* Nyquist freq. */ + const double scale1 = _dsoSig1->get_vDialValue() / 1000.0 * _dsoSig1->get_factor() * DS_CONF_DSO_VDIVS * + _dsoSig1->get_scale() / _dsoSig1->get_view_rect().height(); + const double delta1 = _dsoSig1->get_hw_offset() * scale1; + + const double scale2 = _dsoSig2->get_vDialValue() / 1000.0 * _dsoSig2->get_factor() * DS_CONF_DSO_VDIVS * + _dsoSig2->get_scale() / _dsoSig2->get_view_rect().height(); + const double delta2 = _dsoSig2->get_hw_offset() * scale2; + + const int index1 = _dsoSig1->get_index(); + const int index2 = _dsoSig2->get_index(); + + const int num_channels = snapshot->get_channel_num(); + const uint8_t* value = snapshot->get_samples(0, 0, 0); + _sample_num = snapshot->get_sample_count(); + assert(_sample_num <= _total_sample_num); + + double value1, value2; + for (uint64_t sample = 0; sample < _sample_num; sample++) { + value1 = value[sample * num_channels + index1]; + value2 = value[sample * num_channels + index2]; + switch(_type) { + case MATH_ADD: + _math[sample] = (delta1 - scale1 * value1) + (delta2 - scale2 * value2); + break; + case MATH_SUB: + _math[sample] = (delta1 - scale1 * value1) - (delta2 - scale2 * value2); + break; + case MATH_MUL: + _math[sample] = (delta1 - scale1 * value1) * (delta2 - scale2 * value2); + break; + case MATH_DIV: + _math[sample] = (delta1 - scale1 * value1) / (delta2 - scale2 * value2); + break; + } + } + if (_envelope_en) + append_to_envelope_level(true); + + // stop _math_state = Stopped; } -double MathStack::window(uint64_t i, int type) -{ - const double n_m_1 = _sample_num-1; - switch(type) { - case 1: // Hann window - return 0.5*(1-cos(2*PI*i/n_m_1)); - case 2: // Hamming window - return 0.54-0.46*cos(2*PI*i/n_m_1); - case 3: // Blackman window - return 0.42659-0.49656*cos(2*PI*i/n_m_1) + 0.076849*cos(4*PI*i/n_m_1); - case 4: // Flat_top window - return 1-1.93*cos(2*PI*i/n_m_1)+1.29*cos(4*PI*i/n_m_1)- - 0.388*cos(6*PI*i/n_m_1)+0.028*cos(8*PI*i/n_m_1); - default: - return 1; +void MathStack::reallocate_envelope(Envelope &e) +{ + const uint64_t new_data_length = ((e.length + EnvelopeDataUnit - 1) / + EnvelopeDataUnit) * EnvelopeDataUnit; + if (new_data_length > e.data_length) + { + e.data_length = new_data_length; + } +} + +void MathStack::append_to_envelope_level(bool header) +{ + Envelope &e0 = _envelope_level[0]; + uint64_t prev_length; + EnvelopeSample *dest_ptr; + + if (header) + prev_length = 0; + else + prev_length = e0.length; + e0.length = _sample_num / EnvelopeScaleFactor; + + if (e0.length == 0) + return; + if (e0.length == prev_length) + prev_length = 0; + + // Expand the data buffer to fit the new samples + reallocate_envelope(e0); + + dest_ptr = e0.samples + prev_length; + + // Iterate through the samples to populate the first level mipmap + const double *const stop_src_ptr = (double*)_math.data() + + e0.length * EnvelopeScaleFactor; + for (const double *src_ptr = (double*)_math.data() + + prev_length * EnvelopeScaleFactor; + src_ptr < stop_src_ptr; src_ptr += EnvelopeScaleFactor) + { + const double * begin_src_ptr = + src_ptr; + const double *const end_src_ptr = + src_ptr + EnvelopeScaleFactor; + + EnvelopeSample sub_sample; + sub_sample.min = *begin_src_ptr; + sub_sample.max = *begin_src_ptr; + //begin_src_ptr += _channel_num; + while (begin_src_ptr < end_src_ptr) + { + sub_sample.min = min(sub_sample.min, *begin_src_ptr); + sub_sample.max = max(sub_sample.max, *begin_src_ptr); + begin_src_ptr ++; + } + *dest_ptr++ = sub_sample; + } + + // Compute higher level mipmaps + for (unsigned int level = 1; level < ScaleStepCount; level++) + { + Envelope &e = _envelope_level[level]; + const Envelope &el = _envelope_level[level-1]; + + // Expand the data buffer to fit the new samples + prev_length = e.length; + e.length = el.length / EnvelopeScaleFactor; + + // Break off if there are no more samples to computed +// if (e.length == prev_length) +// break; + if (e.length == prev_length) + prev_length = 0; + + reallocate_envelope(e); + + // Subsample the level lower level + const EnvelopeSample *src_ptr = + el.samples + prev_length * EnvelopeScaleFactor; + const EnvelopeSample *const end_dest_ptr = e.samples + e.length; + for (dest_ptr = e.samples + prev_length; + dest_ptr < end_dest_ptr; dest_ptr++) + { + const EnvelopeSample *const end_src_ptr = + src_ptr + EnvelopeScaleFactor; + + EnvelopeSample sub_sample = *src_ptr++; + while (src_ptr < end_src_ptr) + { + sub_sample.min = min(sub_sample.min, src_ptr->min); + sub_sample.max = max(sub_sample.max, src_ptr->max); + src_ptr++; + } + + *dest_ptr = sub_sample; + } } + + _envelope_done = true; } } // namespace data diff --git a/DSView/pv/data/mathstack.h b/DSView/pv/data/mathstack.h old mode 100644 new mode 100755 index 88c5fca3b3b3f255004cf1c64c7da951c24fd8da..ffb80db45a6f5ddf705cf8f8c4a36f3f3552dce9 --- a/DSView/pv/data/mathstack.h +++ b/DSView/pv/data/mathstack.h @@ -29,8 +29,6 @@ #include #include -#include - #include #include @@ -40,6 +38,7 @@ class SigSession; namespace view { class DsoSignal; +class dslDial; } namespace data { @@ -51,10 +50,6 @@ class MathStack : public QObject, public SignalData { Q_OBJECT -private: - static const QString windows_support[5]; - static const uint64_t length_support[5]; - public: enum math_state { Init, @@ -62,56 +57,95 @@ public: Running }; + enum MathType { + MATH_ADD, + MATH_SUB, + MATH_MUL, + MATH_DIV, + }; + + struct EnvelopeSample + { + double min; + double max; + }; + + struct EnvelopeSection + { + uint64_t start; + unsigned int scale; + uint64_t length; + EnvelopeSample *samples; + }; + +private: + struct Envelope + { + uint64_t length; + uint64_t data_length; + EnvelopeSample *samples; + }; + +private: + static const unsigned int ScaleStepCount = 10; + static const int EnvelopeScalePower; + static const int EnvelopeScaleFactor; + static const float LogEnvelopeScaleFactor; + static const uint64_t EnvelopeDataUnit; + + static const uint64_t vDialValueStep = 1000; + static const int vDialValueCount = 19; + static const uint64_t vDialValue[vDialValueCount]; + static const int vDialUnitCount = 2; + static const QString vDialAddUnit[vDialUnitCount]; + static const QString vDialMulUnit[vDialUnitCount]; + static const QString vDialDivUnit[vDialUnitCount]; + public: - MathStack(pv::SigSession &_session, int index); + MathStack(pv::SigSession &_session, + boost::shared_ptr dsoSig1, + boost::shared_ptr dsoSig2, MathType type); virtual ~MathStack(); void clear(); void init(); + void free_envelop(); + void realloc(uint64_t num); - int get_index() const; - + MathType get_type() const; uint64_t get_sample_num() const; - void set_sample_num(uint64_t num); - - int get_windows_index() const; - void set_windows_index(int index); - const std::vector get_windows_support() const; - const std::vector get_length_support() const; + void enable_envelope(bool enable); - bool dc_ignored() const; - void set_dc_ignore(bool ignore); + uint64_t default_vDialValue(); + view::dslDial *get_vDial(); + QString get_unit(int level); + double get_math_scale(); - int get_sample_interval() const; - void set_sample_interval(int interval); + const double *get_math(uint64_t start) const; + void get_math_envelope_section(EnvelopeSection &s, + uint64_t start, uint64_t end, float min_length) const; - const std::vector get_fft_spectrum() const; - double get_fft_spectrum(uint64_t index); - - void calc_fft(); - - double window(uint64_t i, int type); + void calc_math(); + void reallocate_envelope(Envelope &e); + void append_to_envelope_level(bool header); signals: private: pv::SigSession &_session; + boost::shared_ptr _dsoSig1; + boost::shared_ptr _dsoSig2; - int _index; + MathType _type; uint64_t _sample_num; - int _windows_index; - bool _dc_ignore; - int _sample_interval; - - boost::shared_ptr _snapshot; - - std::unique_ptr _math_thread; + uint64_t _total_sample_num; math_state _math_state; - fftw_plan _fft_plan; - std::vector _xn; - std::vector _xk; - std::vector _power_spectrum; + struct Envelope _envelope_level[ScaleStepCount]; + std::vector _math; + + bool _envelope_en; + bool _envelope_done; }; } // namespace data diff --git a/DSView/pv/data/signaldata.cpp b/DSView/pv/data/signaldata.cpp old mode 100644 new mode 100755 diff --git a/DSView/pv/data/signaldata.h b/DSView/pv/data/signaldata.h old mode 100644 new mode 100755 diff --git a/DSView/pv/data/snapshot.cpp b/DSView/pv/data/snapshot.cpp old mode 100644 new mode 100755 diff --git a/DSView/pv/data/snapshot.h b/DSView/pv/data/snapshot.h old mode 100644 new mode 100755 diff --git a/DSView/pv/data/spectrumstack.cpp b/DSView/pv/data/spectrumstack.cpp new file mode 100755 index 0000000000000000000000000000000000000000..d040eb9be27e3539e30564cbe380070963c95833 --- /dev/null +++ b/DSView/pv/data/spectrumstack.cpp @@ -0,0 +1,247 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2016 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "spectrumstack.h" + +#include +#include + +#include +#include +#include +#include + +#define PI 3.1415 + +using namespace boost; +using namespace std; + +namespace pv { +namespace data { + +const QString SpectrumStack::windows_support[5] = { + QT_TR_NOOP("Rectangle"), + QT_TR_NOOP("Hann"), + QT_TR_NOOP("Hamming"), + QT_TR_NOOP("Blackman"), + QT_TR_NOOP("Flat_top") +}; + +const uint64_t SpectrumStack::length_support[5] = { + 1024, + 2048, + 4096, + 8192, + 16384, +}; + +SpectrumStack::SpectrumStack(pv::SigSession &session, int index) : + _session(session), + _index(index), + _dc_ignore(true), + _sample_interval(1), + _spectrum_state(Init), + _fft_plan(NULL) +{ +} + +SpectrumStack::~SpectrumStack() +{ + _xn.clear(); + _xk.clear(); + _power_spectrum.clear(); + if (_fft_plan) + fftw_destroy_plan(_fft_plan); +} + +void SpectrumStack::clear() +{ +} + +void SpectrumStack::init() +{ +} + +int SpectrumStack::get_index() const +{ + return _index; +} + +uint64_t SpectrumStack::get_sample_num() const +{ + return _sample_num; +} + +void SpectrumStack::set_sample_num(uint64_t num) +{ + _sample_num = num; + _xn.resize(_sample_num); + _xk.resize(_sample_num); + _power_spectrum.resize(_sample_num/2+1); + _fft_plan = fftw_plan_r2r_1d(_sample_num, _xn.data(), _xk.data(), + FFTW_R2HC, FFTW_ESTIMATE); +} + +int SpectrumStack::get_windows_index() const +{ + return _windows_index; +} + +void SpectrumStack::set_windows_index(int index) +{ + _windows_index = index; +} + +bool SpectrumStack::dc_ignored() const +{ + return _dc_ignore; +} + +void SpectrumStack::set_dc_ignore(bool ignore) +{ + _dc_ignore = ignore; +} + +int SpectrumStack::get_sample_interval() const +{ + return _sample_interval; +} + +void SpectrumStack::set_sample_interval(int interval) +{ + _sample_interval = interval; +} + +const std::vector SpectrumStack::get_windows_support() const +{ + std::vector windows; + for (size_t i = 0; i < sizeof(windows_support)/sizeof(windows_support[0]); i++) + { + windows.push_back(windows_support[i]); + } + return windows; +} + +const std::vector SpectrumStack::get_length_support() const +{ + std::vector length; + for (size_t i = 0; i < sizeof(length_support)/sizeof(length_support[0]); i++) + { + length.push_back(length_support[i]); + } + return length; +} + +const std::vector SpectrumStack::get_fft_spectrum() const +{ + std::vector empty; + if (_spectrum_state == Stopped) + return _power_spectrum; + else + return empty; +} + +double SpectrumStack::get_fft_spectrum(uint64_t index) +{ + double ret = -1; + if (_spectrum_state == Stopped && index < _power_spectrum.size()) + ret = _power_spectrum[index]; + + return ret; +} + +void SpectrumStack::calc_fft() +{ + _spectrum_state = Running; + // Get the dso data + boost::shared_ptr data; + boost::shared_ptr dsoSig; + BOOST_FOREACH(const boost::shared_ptr s, _session.get_signals()) { + if ((dsoSig = dynamic_pointer_cast(s))) { + if (dsoSig->get_index() == _index && dsoSig->enabled()) { + data = dsoSig->dso_data(); + break; + } + } + } + + if (!data) + return; + + // Check we have a snapshot of data + const deque< boost::shared_ptr > &snapshots = + data->get_snapshots(); + if (snapshots.empty()) + return; + _snapshot = snapshots.front(); + + if (_snapshot->get_sample_count() < _sample_num*_sample_interval) + return; + + // Get the samplerate + _samplerate = data->samplerate(); + if (_samplerate == 0.0) + _samplerate = 1.0; + + // prepare _xn data + const int offset = dsoSig->get_hw_offset(); + const double vscale = dsoSig->get_vDialValue() * dsoSig->get_factor() * DS_CONF_DSO_VDIVS / (1000*255.0); + const uint16_t step = _snapshot->get_channel_num() * _sample_interval; + const uint8_t *const samples = _snapshot->get_samples(0, _sample_num*_sample_interval-1, _index); + double wsum = 0; + for (unsigned int i = 0; i < _sample_num; i++) { + double w = window(i, _windows_index); + _xn[i] = (samples[i*step] - offset) * vscale * w; + wsum += w; + } + + // fft + fftw_execute(_fft_plan); + + // calculate power spectrum + _power_spectrum[0] = abs(_xk[0])/wsum; /* DC component */ + for (unsigned int k = 1; k < (_sample_num + 1) / 2; ++k) /* (k < N/2 rounded up) */ + _power_spectrum[k] = sqrt((_xk[k]*_xk[k] + _xk[_sample_num-k]*_xk[_sample_num-k]) * 2) / wsum; + if (_sample_num % 2 == 0) /* N is even */ + _power_spectrum[_sample_num/2] = abs(_xk[_sample_num/2])/wsum; /* Nyquist freq. */ + + _spectrum_state = Stopped; +} + +double SpectrumStack::window(uint64_t i, int type) +{ + const double n_m_1 = _sample_num-1; + switch(type) { + case 1: // Hann window + return 0.5*(1-cos(2*PI*i/n_m_1)); + case 2: // Hamming window + return 0.54-0.46*cos(2*PI*i/n_m_1); + case 3: // Blackman window + return 0.42659-0.49656*cos(2*PI*i/n_m_1) + 0.076849*cos(4*PI*i/n_m_1); + case 4: // Flat_top window + return 1-1.93*cos(2*PI*i/n_m_1)+1.29*cos(4*PI*i/n_m_1)- + 0.388*cos(6*PI*i/n_m_1)+0.028*cos(8*PI*i/n_m_1); + default: + return 1; + } +} + +} // namespace data +} // namespace pv diff --git a/DSView/pv/data/spectrumstack.h b/DSView/pv/data/spectrumstack.h new file mode 100755 index 0000000000000000000000000000000000000000..caa4d268136cf5cc2e5ef391f57d8ef50c8d0562 --- /dev/null +++ b/DSView/pv/data/spectrumstack.h @@ -0,0 +1,118 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2016 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef DSVIEW_PV_DATA_SPECTRUMSTACK_H +#define DSVIEW_PV_DATA_SPECTRUMSTACK_H + +#include "signaldata.h" + +#include + +#include +#include +#include + +#include + +#include +#include + +namespace pv { + +class SigSession; + +namespace view { +class DsoSignal; +} + +namespace data { + +class DsoSnapshot; +class Dso; + +class SpectrumStack : public QObject, public SignalData +{ + Q_OBJECT + +private: + static const QString windows_support[5]; + static const uint64_t length_support[5]; + +public: + enum spectrum_state { + Init, + Stopped, + Running + }; + +public: + SpectrumStack(pv::SigSession &_session, int index); + virtual ~SpectrumStack(); + void clear(); + void init(); + + int get_index() const; + + uint64_t get_sample_num() const; + void set_sample_num(uint64_t num); + + int get_windows_index() const; + void set_windows_index(int index); + + const std::vector get_windows_support() const; + const std::vector get_length_support() const; + + bool dc_ignored() const; + void set_dc_ignore(bool ignore); + + int get_sample_interval() const; + void set_sample_interval(int interval); + + const std::vector get_fft_spectrum() const; + double get_fft_spectrum(uint64_t index); + + void calc_fft(); + + double window(uint64_t i, int type); + +signals: + +private: + pv::SigSession &_session; + + int _index; + uint64_t _sample_num; + int _windows_index; + bool _dc_ignore; + int _sample_interval; + + boost::shared_ptr _snapshot; + spectrum_state _spectrum_state; + + fftw_plan _fft_plan; + std::vector _xn; + std::vector _xk; + std::vector _power_spectrum; +}; + +} // namespace data +} // namespace pv + +#endif // DSVIEW_PV_DATA_SPECTRUMSTACK_H diff --git a/DSView/pv/device/device.cpp b/DSView/pv/device/device.cpp old mode 100644 new mode 100755 index 8214f415d8eca4e150071824b6a1e39148b1b96a..4eb77b33eb3f1e3f2e7c6c8bcc72932bb260b2eb --- a/DSView/pv/device/device.cpp +++ b/DSView/pv/device/device.cpp @@ -40,7 +40,7 @@ sr_dev_inst* Device::dev_inst() const return _sdi; } -void Device::use(SigSession *owner) throw(QString) +void Device::use(SigSession *owner) { DevInst::use(owner); diff --git a/DSView/pv/device/device.h b/DSView/pv/device/device.h old mode 100644 new mode 100755 index a98ffc0d1e71219dec6327ae2284727f6b668687..f1ec24f1a5ad6dab89e48c0ba96d8c091a16614e --- a/DSView/pv/device/device.h +++ b/DSView/pv/device/device.h @@ -34,7 +34,7 @@ public: sr_dev_inst* dev_inst() const; - void use(SigSession *owner) throw(QString); + void use(SigSession *owner); void release(); diff --git a/DSView/pv/device/devinst.cpp b/DSView/pv/device/devinst.cpp old mode 100644 new mode 100755 index 494a681e738fac26866625a01b5c4570dc610b10..6aeeeb876c1ac4fbf5be2aa463877ef9ffafdeef --- a/DSView/pv/device/devinst.cpp +++ b/DSView/pv/device/devinst.cpp @@ -50,7 +50,7 @@ void* DevInst::get_id() const return _id; } -void DevInst::use(SigSession *owner) throw(QString) +void DevInst::use(SigSession *owner) { assert(owner); assert(!_owner); @@ -125,7 +125,7 @@ uint64_t DevInst::get_sample_limit() uint64_t sample_limit; GVariant* gvar = get_config(NULL, NULL, SR_CONF_LIMIT_SAMPLES); if (gvar != NULL) { - sample_limit = g_variant_get_uint64(gvar); + sample_limit = g_variant_get_uint64(gvar); g_variant_unref(gvar); } else { sample_limit = 0U; diff --git a/DSView/pv/device/devinst.h b/DSView/pv/device/devinst.h old mode 100644 new mode 100755 index c35fd95245a475c616adf08d8f94399d71ef3e7d..b7c7f8c38b4e33d974e06df66b285953d722ab05 --- a/DSView/pv/device/devinst.h +++ b/DSView/pv/device/devinst.h @@ -53,7 +53,7 @@ protected: public: virtual sr_dev_inst* dev_inst() const = 0; - virtual void use(SigSession *owner) throw(QString); + virtual void use(SigSession *owner); virtual void release(); diff --git a/DSView/pv/device/file.cpp b/DSView/pv/device/file.cpp old mode 100644 new mode 100755 index 04b6eb4acfba6d8cd338c2daa8be97b0d54b836d..46376082c4cb06cc719d730220416e3c3f87eb0b --- a/DSView/pv/device/file.cpp +++ b/DSView/pv/device/file.cpp @@ -91,10 +91,43 @@ QJsonArray File::get_decoders() dec_array = sessionDoc.array(); } } + + zip_close(archive); } return dec_array; } +QJsonDocument File::get_session() +{ + struct zip *archive; + struct zip_file *zf; + struct zip_stat zs; + int ret; + char *dec_file; + QJsonDocument sessionDoc; + QJsonParseError error; + + archive = zip_open(_path.toLocal8Bit().data(), 0, &ret); + if (archive) { + /* read "decoders" */ + if (zip_stat(archive, "session", 0, &zs) != -1) { + dec_file = (char *)g_try_malloc(zs.size); + if (dec_file) { + zf = zip_fopen_index(archive, zs.index, 0); + zip_fread(zf, dec_file, zs.size); + zip_fclose(zf); + + //QString sessionData = QString::fromUtf8(dec_file); + sessionDoc = QJsonDocument::fromJson(QByteArray::fromRawData(dec_file, zs.size), &error); + } + } + + zip_close(archive); + } + + return sessionDoc; +} + } // device } // pv diff --git a/DSView/pv/device/file.h b/DSView/pv/device/file.h old mode 100644 new mode 100755 index 000b950bc060f61c1b4894fd6e48d8efe477cc34..d4299e7b9b102375dd08d6e285dc42832e8eb0fa --- a/DSView/pv/device/file.h +++ b/DSView/pv/device/file.h @@ -26,6 +26,7 @@ #include #include +#include #include "devinst.h" @@ -42,6 +43,8 @@ public: QJsonArray get_decoders(); + QJsonDocument get_session(); + public: QString format_device_title() const; diff --git a/DSView/pv/device/inputfile.cpp b/DSView/pv/device/inputfile.cpp old mode 100644 new mode 100755 index 84d8957b4973c010fb8b13d3f11a4717b15a2ea4..32b63cc4e872eff59c0234b80a82808a362ee4e3 --- a/DSView/pv/device/inputfile.cpp +++ b/DSView/pv/device/inputfile.cpp @@ -43,7 +43,7 @@ sr_dev_inst* InputFile::dev_inst() const return _input->sdi; } -void InputFile::use(SigSession *owner) throw(QString) +void InputFile::use(SigSession *owner) { (void)owner; assert(!_input); diff --git a/DSView/pv/device/inputfile.h b/DSView/pv/device/inputfile.h old mode 100644 new mode 100755 index c063deaf54c8a8bbf266908e5357d84ac2129222..e1c1e1792455345d9b110cde5c2b5da8fc294db2 --- a/DSView/pv/device/inputfile.h +++ b/DSView/pv/device/inputfile.h @@ -39,7 +39,7 @@ public: sr_dev_inst* dev_inst() const; - virtual void use(SigSession *owner) throw(QString); + virtual void use(SigSession *owner); virtual void release(); diff --git a/DSView/pv/device/sessionfile.cpp b/DSView/pv/device/sessionfile.cpp old mode 100644 new mode 100755 index 5540e42b763fbbe00e7c4356a99baffcb56a5af9..2a3368a5abd9af75af475f39ada6b10b79b1f6d1 --- a/DSView/pv/device/sessionfile.cpp +++ b/DSView/pv/device/sessionfile.cpp @@ -35,7 +35,7 @@ sr_dev_inst* SessionFile::dev_inst() const return _sdi; } -void SessionFile::use(SigSession *owner) throw(QString) +void SessionFile::use(SigSession *owner) { assert(!_sdi); diff --git a/DSView/pv/device/sessionfile.h b/DSView/pv/device/sessionfile.h old mode 100644 new mode 100755 index 51d6d3f22dc374abf946ca594a30e9b336d5a624..08783bddea5c10cebb1274380b2b2a50b105a3b4 --- a/DSView/pv/device/sessionfile.h +++ b/DSView/pv/device/sessionfile.h @@ -34,7 +34,7 @@ public: sr_dev_inst* dev_inst() const; - virtual void use(SigSession *owner) throw(QString); + virtual void use(SigSession *owner); virtual void release(); diff --git a/DSView/pv/devicemanager.cpp b/DSView/pv/devicemanager.cpp old mode 100644 new mode 100755 index 3b760f93fa21abf79536d84fb932dd9763961db2..d7778be56657db5a34ac2b5bce776ac08dfccb35 --- a/DSView/pv/devicemanager.cpp +++ b/DSView/pv/devicemanager.cpp @@ -72,6 +72,21 @@ void DeviceManager::add_device(boost::shared_ptr device) _devices.push_front(device); } +void DeviceManager::del_device(boost::shared_ptr device) +{ + assert(device); + BOOST_FOREACH(shared_ptr dev, _devices) { + assert(dev); + if(dev == device) { + dev->release(); + break; + } + } + if (std::find(_devices.begin(), _devices.end(), device) != + _devices.end()) + _devices.remove(device); +} + std::list > DeviceManager::driver_scan( struct sr_dev_driver *const driver, GSList *const drvopts) { diff --git a/DSView/pv/devicemanager.h b/DSView/pv/devicemanager.h old mode 100644 new mode 100755 index 3f0b313ad8b4be010444110e5f0b43ee264b0936..426b9aa8d43982436777f06e15ef25f62ba40311 --- a/DSView/pv/devicemanager.h +++ b/DSView/pv/devicemanager.h @@ -61,6 +61,7 @@ public: const std::list< boost::shared_ptr >& devices() const; void add_device(boost::shared_ptr device); + void del_device(boost::shared_ptr device); std::list< boost::shared_ptr > driver_scan( struct sr_dev_driver *const driver, diff --git a/DSView/pv/dialogs/about.cpp b/DSView/pv/dialogs/about.cpp old mode 100644 new mode 100755 index 4b800908d1441f14d4c78c5172e6371808ba9fa6..5dea3737240481292c73c488373acd642aad09e6 --- a/DSView/pv/dialogs/about.cpp +++ b/DSView/pv/dialogs/about.cpp @@ -54,9 +54,11 @@ About::About(QWidget *parent) : QString url = tr("Website: %1
" "Gitbub: %2
" + "Copyright:%3
" "

") .arg(QApplication::organizationDomain()) - .arg("https://github.com/DreamSourceLab/DSView"); + .arg("https://github.com/DreamSourceLab/DSView") + .arg(tr("© DreamSourceLab. All rights reserved.")); QString thanks = tr("Special Thanks
" "All backers on kickstarter
" @@ -67,9 +69,13 @@ About::About(QWidget *parent) : .arg("http://sigrok.org/"); QString changlogs = tr("Changelogs
"); + #ifndef Q_OS_LINUX + QDir dir(QCoreApplication::applicationDirPath()); + #else QDir dir(DS_RES_PATH); dir.cdUp(); - QString filename = dir.absolutePath() + "/NEWS"; + #endif + QString filename = dir.absolutePath() + "/NEWS" + QString::number(qApp->property("Language").toInt()); QFile news(filename); if (news.open(QIODevice::ReadOnly)) { QTextCodec *code=QTextCodec::codecForName("UTF-8"); diff --git a/DSView/pv/dialogs/about.h b/DSView/pv/dialogs/about.h old mode 100644 new mode 100755 diff --git a/DSView/pv/dialogs/calibration.cpp b/DSView/pv/dialogs/calibration.cpp old mode 100644 new mode 100755 index f3d231d373abbd1797730c32edcb8185a5105a20..ab11ca95903fc75d16de2ea13421e53806a691f2 --- a/DSView/pv/dialogs/calibration.cpp +++ b/DSView/pv/dialogs/calibration.cpp @@ -30,6 +30,7 @@ #include #include "../view/trace.h" +#include "../dialogs/dsmessagebox.h" using namespace boost; using namespace std; @@ -39,6 +40,7 @@ namespace dialogs { const QString Calibration::VGAIN = QT_TR_NOOP(" VGAIN"); const QString Calibration::VOFF = QT_TR_NOOP(" VOFF"); +const QString Calibration::VCOMB = QT_TR_NOOP(" VCOMB"); Calibration::Calibration(QWidget *parent) : DSDialog(parent) @@ -52,9 +54,10 @@ Calibration::Calibration(QWidget *parent) : this->setModal(false); _dev_inst = NULL; - _save_btn = new QPushButton(tr("Save"), this); - _reset_btn = new QPushButton(tr("Reset"), this); - _exit_btn = new QPushButton(tr("Exit"), this); + _save_btn = new QPushButton(this); + _abort_btn = new QPushButton(this); + _reset_btn = new QPushButton(this); + _exit_btn = new QPushButton(this); _flayout = new QFormLayout(); _flayout->setVerticalSpacing(10); @@ -64,21 +67,43 @@ Calibration::Calibration(QWidget *parent) : QGridLayout *glayout = new QGridLayout(); glayout->setVerticalSpacing(5); - glayout->addLayout(_flayout, 1, 0, 1, 5); + glayout->addLayout(_flayout, 1, 0, 1, 7); glayout->addWidget(_save_btn, 2, 0); glayout->addWidget(new QWidget(this), 2, 1); glayout->setColumnStretch(1, 1); - glayout->addWidget(_reset_btn, 2, 2); + glayout->addWidget(_abort_btn, 2, 2); glayout->addWidget(new QWidget(this), 2, 3); glayout->setColumnStretch(3, 1); - glayout->addWidget(_exit_btn, 2, 4); + glayout->addWidget(_reset_btn, 2, 4); + glayout->addWidget(new QWidget(this), 2, 5); + glayout->setColumnStretch(5, 1); + glayout->addWidget(_exit_btn, 2, 6); layout()->addLayout(glayout); - setTitle(tr("Manual Calibration")); connect(_save_btn, SIGNAL(clicked()), this, SLOT(on_save())); + connect(_abort_btn, SIGNAL(clicked()), this, SLOT(on_abort())); connect(_reset_btn, SIGNAL(clicked()), this, SLOT(on_reset())); connect(_exit_btn, SIGNAL(clicked()), this, SLOT(reject())); + + retranslateUi(); +} + +void Calibration::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + retranslateUi(); + DSDialog::changeEvent(event); +} + +void Calibration::retranslateUi() +{ + _save_btn->setText(tr("Save")); + _abort_btn->setText(tr("Abort")); + _reset_btn->setText(tr("Reset")); + _exit_btn->setText(tr("Exit")); + + setTitle(tr("Manual Calibration")); } void Calibration::set_device(boost::shared_ptr dev_inst) @@ -135,12 +160,12 @@ void Calibration::set_device(boost::shared_ptr dev_inst) uint64_t voff = 0; uint16_t voff_range = 0; - gvar = _dev_inst->get_config(probe, NULL, SR_CONF_PROBE_VOFF); + gvar = _dev_inst->get_config(probe, NULL, SR_CONF_PROBE_PREOFF); if (gvar != NULL) { voff = g_variant_get_uint16(gvar); g_variant_unref(gvar); } - gvar = _dev_inst->get_config(probe, NULL, SR_CONF_PROBE_VOFF_RANGE); + gvar = _dev_inst->get_config(probe, NULL, SR_CONF_PROBE_PREOFF_MARGIN); if (gvar != NULL) { voff_range = g_variant_get_uint16(gvar); g_variant_unref(gvar); @@ -155,6 +180,31 @@ void Calibration::set_device(boost::shared_ptr dev_inst) _slider_list.push_back(off_slider); _label_list.push_back(off_label); + bool comb_comp_en = false; + gvar = _dev_inst->get_config(probe, NULL, SR_CONF_PROBE_COMB_COMP_EN); + if (gvar != NULL) { + comb_comp_en = g_variant_get_boolean(gvar); + g_variant_unref(gvar); + } + if (comb_comp_en) { + int16_t comb_comp = 0; + gvar = _dev_inst->get_config(probe, NULL, SR_CONF_PROBE_COMB_COMP); + if (gvar != NULL) { + comb_comp = g_variant_get_int16(gvar); + g_variant_unref(gvar); + } + QSlider *comp_slider = new QSlider(Qt::Horizontal, this); + comp_slider->setRange(-127, 127); + comp_slider->setValue(comb_comp); + comp_slider->setObjectName(VCOMB+probe->index); + QString comp_string = tr("Channel") + QString::number(probe->index) + VCOMB; + QLabel *comp_label = new QLabel(comp_string, this); + _flayout->addRow(comp_label, comp_slider); + _slider_list.push_back(comp_slider); + _label_list.push_back(comp_label); + connect(comp_slider, SIGNAL(valueChanged(int)), this, SLOT(set_value(int))); + } + connect(gain_slider, SIGNAL(valueChanged(int)), this, SLOT(set_value(int))); connect(off_slider, SIGNAL(valueChanged(int)), this, SLOT(set_value(int))); } @@ -194,9 +244,13 @@ void Calibration::set_value(int value) } break; } else if (sc->objectName() == VOFF+probe->index) { - _dev_inst->set_config(probe, NULL, SR_CONF_PROBE_VOFF, + _dev_inst->set_config(probe, NULL, SR_CONF_PROBE_PREOFF, g_variant_new_uint16(value)); break; + } else if (sc->objectName() == VCOMB+probe->index) { + _dev_inst->set_config(probe, NULL, SR_CONF_PROBE_COMB_COMP, + g_variant_new_int16(value)); + break; } } } @@ -212,7 +266,7 @@ void Calibration::on_save() //while( QTime::currentTime() < dieTime ); }); Qt::WindowFlags flags = Qt::CustomizeWindowHint; - QProgressDialog dlg(tr("Save Calibration Result... It can take a while."), + QProgressDialog dlg(tr("Save calibration results... It can take a while."), tr("Cancel"),0,0,this,flags); dlg.setWindowModality(Qt::WindowModal); dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | @@ -227,7 +281,7 @@ void Calibration::on_save() this->show(); } -void Calibration::on_reset() +void Calibration::on_abort() { this->hide(); QFuture future; @@ -239,7 +293,7 @@ void Calibration::on_reset() //while( QTime::currentTime() < dieTime ); }); Qt::WindowFlags flags = Qt::CustomizeWindowHint; - QProgressDialog dlg(tr("Reset Calibration Result... It can take a while."), + QProgressDialog dlg(tr("Reload last calibration results... It can take a while."), tr("Cancel"),0,0,this,flags); dlg.setWindowModality(Qt::WindowModal); dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | @@ -280,12 +334,12 @@ void Calibration::reload_value() uint64_t voff = 0; uint16_t voff_range = 0; - gvar = _dev_inst->get_config(probe, NULL, SR_CONF_PROBE_VOFF); + gvar = _dev_inst->get_config(probe, NULL, SR_CONF_PROBE_PREOFF); if (gvar != NULL) { voff = g_variant_get_uint16(gvar); g_variant_unref(gvar); } - gvar = _dev_inst->get_config(probe, NULL, SR_CONF_PROBE_VOFF_RANGE); + gvar = _dev_inst->get_config(probe, NULL, SR_CONF_PROBE_PREOFF_MARGIN); if (gvar != NULL) { voff_range = g_variant_get_uint16(gvar); g_variant_unref(gvar); @@ -304,5 +358,21 @@ void Calibration::reload_value() } } +void Calibration::on_reset() +{ + + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Attention")); + msg.mBox()->setInformativeText(tr("All calibration settings will become the defualt values!")); + msg.mBox()->addButton(tr("Ok"), QMessageBox::AcceptRole); + msg.mBox()->addButton(tr("Cancel"), QMessageBox::RejectRole); + msg.mBox()->setIcon(QMessageBox::Warning); + if (msg.exec()) { + _dev_inst->set_config(NULL, NULL, SR_CONF_ZERO_DEFAULT, + g_variant_new_boolean(true)); + reload_value(); + } +} + } // namespace dialogs } // namespace pv diff --git a/DSView/pv/dialogs/calibration.h b/DSView/pv/dialogs/calibration.h old mode 100644 new mode 100755 index 9e469f1b07bae5e47112b130d42d8f06fc02e23c..97bf7ce2b38812b39bf48370a07f7906bca15b1d --- a/DSView/pv/dialogs/calibration.h +++ b/DSView/pv/dialogs/calibration.h @@ -46,6 +46,7 @@ class Calibration : public DSDialog private: static const QString VGAIN; static const QString VOFF; + static const QString VCOMB; public: Calibration(QWidget *parent); @@ -55,9 +56,14 @@ protected: void accept(); void reject(); +private: + void changeEvent(QEvent *event); + void retranslateUi(); + private slots: void set_value(int value); void on_save(); + void on_abort(); void on_reset(); void reload_value(); @@ -66,6 +72,7 @@ private: toolbars::TitleBar *_titlebar; QPushButton *_save_btn; + QPushButton *_abort_btn; QPushButton *_reset_btn; QPushButton *_exit_btn; QFormLayout *_flayout; diff --git a/DSView/pv/dialogs/deviceoptions.cpp b/DSView/pv/dialogs/deviceoptions.cpp old mode 100644 new mode 100755 index 79fd0191b9d33f42532e2cf21be5ab48e15ec467..4ffd80802967c0dde1ab995341a13f2d78ccc97d --- a/DSView/pv/dialogs/deviceoptions.cpp +++ b/DSView/pv/dialogs/deviceoptions.cpp @@ -144,7 +144,7 @@ QGridLayout * DeviceOptions::get_property_form(QWidget * parent) BOOST_FOREACH(boost::shared_ptr p, properties) { assert(p); - const QString label = p->labeled_widget() ? QString() : p->name(); + const QString label = p->labeled_widget() ? QString() : p->label(); layout->addWidget(new QLabel(label, parent), i, 0); if (label == tr("Operation Mode")) layout->addWidget(p->get_widget(parent, true), i, 1); @@ -196,7 +196,8 @@ void DeviceOptions::logic_probes(QGridLayout &layout) ch_opts->setChecked(true); } } - g_variant_unref(gvar_opts); + if (gvar_opts) + g_variant_unref(gvar_opts); } } @@ -307,12 +308,14 @@ void DeviceOptions::zero_adj() dialogs::DSMessageBox msg(this); msg.mBox()->setText(tr("Information")); msg.mBox()->setInformativeText(tr("Auto Calibration program will be started. Please keep all channels out of singal input. It can take a while!")); - //msg.mBox()->setStandardButtons(QMessageBox::); msg.mBox()->addButton(tr("Ok"), QMessageBox::AcceptRole); msg.mBox()->addButton(tr("Cancel"), QMessageBox::RejectRole); msg.mBox()->setIcon(QMessageBox::Information); + if (msg.exec()) { _dev_inst->set_config(NULL, NULL, SR_CONF_ZERO, g_variant_new_boolean(true)); + } else { + _dev_inst->set_config(NULL, NULL, SR_CONF_ZERO, g_variant_new_boolean(false)); } } @@ -366,6 +369,22 @@ void DeviceOptions::channel_check() _dynamic_box->setVisible(_dynamic_box->title() != NULL); } +void DeviceOptions::analog_channel_check() +{ + QCheckBox* sc=dynamic_cast(sender()); + if(sc != NULL) { + for (const GSList *l = _dev_inst->dev_inst()->channels; l; l = l->next) { + sr_channel *const probe = (sr_channel*)l->data; + assert(probe); + if (sc->property("index").toInt() == probe->index) + _dev_inst->set_config(probe, NULL, SR_CONF_PROBE_MAP_DEFAULT, + g_variant_new_boolean(sc->isChecked())); + } + } + dynamic_widget(_dynamic_layout); + _dynamic_box->setVisible(_dynamic_box->title() != NULL); +} + void DeviceOptions::channel_enable() { if (_dev_inst->dev_inst()->mode == LOGIC) { @@ -491,7 +510,6 @@ void DeviceOptions::analog_probes(QGridLayout &layout) probe_layout->addWidget(en_label, 0, 0, 1, 1); probe_layout->addWidget(probe_checkBox, 0, 1, 1, 3); - pv::prop::binding::ProbeOptions *probe_options_binding = new pv::prop::binding::ProbeOptions(_dev_inst->dev_inst(), probe); const vector< boost::shared_ptr > &properties = @@ -500,9 +518,26 @@ void DeviceOptions::analog_probes(QGridLayout &layout) BOOST_FOREACH(boost::shared_ptr p, properties) { assert(p); - probe_layout->addWidget(new QLabel(p->name(), probe_widget), i, 0, 1, 1); - QWidget *pow = p->get_widget(probe_widget); + const QString label = p->labeled_widget() ? QString() : p->label(); + probe_layout->addWidget(new QLabel(label, probe_widget), i, 0, 1, 1); + + QWidget * pow = p->get_widget(probe_widget); pow->setEnabled(probe_checkBox->isChecked()); + if (p->name().contains("Map Default")) { + pow->setProperty("index", probe->index); + connect(pow, SIGNAL(clicked()), this, SLOT(analog_channel_check())); + } else { + if (probe_checkBox->isChecked() && p->name().contains("Map")) { + bool map_default = true; + GVariant* gvar = _dev_inst->get_config(probe, NULL, SR_CONF_PROBE_MAP_DEFAULT); + if (gvar != NULL) { + map_default =g_variant_get_boolean(gvar); + g_variant_unref(gvar); + } + if (map_default) + pow->setEnabled(false); + } + } probe_layout->addWidget(pow, i, 1, 1, 3); i++; } diff --git a/DSView/pv/dialogs/deviceoptions.h b/DSView/pv/dialogs/deviceoptions.h old mode 100644 new mode 100755 index 1deae4410d710fba7bd67b504fa590725cb7f003..0b9591f7444f19ed3277d018bd458e91784ace3e --- a/DSView/pv/dialogs/deviceoptions.h +++ b/DSView/pv/dialogs/deviceoptions.h @@ -78,6 +78,7 @@ private slots: void zero_adj(); void mode_check(); void channel_check(); + void analog_channel_check(); void on_calibration(); void channel_enable(); diff --git a/DSView/pv/dialogs/dsdialog.cpp b/DSView/pv/dialogs/dsdialog.cpp old mode 100644 new mode 100755 diff --git a/DSView/pv/dialogs/dsdialog.h b/DSView/pv/dialogs/dsdialog.h old mode 100644 new mode 100755 diff --git a/DSView/pv/dialogs/dsmessagebox.cpp b/DSView/pv/dialogs/dsmessagebox.cpp old mode 100644 new mode 100755 diff --git a/DSView/pv/dialogs/dsmessagebox.h b/DSView/pv/dialogs/dsmessagebox.h old mode 100644 new mode 100755 diff --git a/DSView/pv/dialogs/dsomeasure.cpp b/DSView/pv/dialogs/dsomeasure.cpp old mode 100644 new mode 100755 index b0cf2716d008acfae985c0f37e67cfc22c5e2932..d1acaa1913eceb2b277098a77598ed7b94eccf9f --- a/DSView/pv/dialogs/dsomeasure.cpp +++ b/DSView/pv/dialogs/dsomeasure.cpp @@ -21,9 +21,14 @@ #include "dsomeasure.h" #include "../device/devinst.h" +#include "../sigsession.h" +#include "../view/view.h" #include #include +#include +#include +#include #include @@ -34,31 +39,74 @@ using namespace pv::view; namespace pv { namespace dialogs { -DsoMeasure::DsoMeasure(QWidget *parent, boost::shared_ptr dsoSig) : - DSDialog(parent), - _dsoSig(dsoSig), - _button_box(QDialogButtonBox::Ok, +DsoMeasure::DsoMeasure(SigSession &session, View &parent, + unsigned int position, int last_sig_index) : + DSDialog((QWidget *)&parent), + _session(session), + _view(parent), + _position(position), + _button_box(QDialogButtonBox::Reset | QDialogButtonBox::Cancel, Qt::Horizontal, this) { - setMinimumWidth(300); - - for (int i=DSO_MS_BEGIN+1; iget_ms_string(i), this); - checkBox->setProperty("id", QVariant(i)); - checkBox->setChecked(dsoSig->get_ms_en(i)); - _layout.addWidget(checkBox); - connect(checkBox, SIGNAL(toggled(bool)), this, SLOT(set_measure(bool))); + setMinimumSize(500, 400); + + _measure_tab = new QTabWidget(this); + _measure_tab->setTabPosition(QTabWidget::West); + _measure_tab->setUsesScrollButtons(false); + + BOOST_FOREACH(const boost::shared_ptr s, _session.get_signals()) { + boost::shared_ptr dsoSig; + if ((dsoSig = dynamic_pointer_cast(s)) && dsoSig->enabled()) { + QWidget *measure_widget = new QWidget(this); + this->add_measure(measure_widget, dsoSig); + _measure_tab->addTab(measure_widget, QString::number(dsoSig->get_index())); + _measure_tab->tabBar()->setMinimumHeight(30); + _measure_tab->tabBar()->setPalette(QPalette(Qt::red)); + measure_widget->setProperty("index", dsoSig->get_index()); + if (dsoSig->get_index() == last_sig_index) + _measure_tab->setCurrentIndex(last_sig_index); + } } - _layout.addWidget(&_button_box); + _layout.addWidget(_measure_tab); + _layout.addWidget(&_button_box, Qt::AlignHCenter | Qt::AlignBottom); layout()->addLayout(&_layout); setTitle(tr("Measurements")); - connect(&_button_box, SIGNAL(accepted()), this, SLOT(accept())); - connect(&_button_box, SIGNAL(rejected()), this, SLOT(accept())); + connect(_button_box.button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); + connect(_button_box.button(QDialogButtonBox::Reset), SIGNAL(clicked()), this, SLOT(reset())); + connect(_session.get_device().get(), SIGNAL(device_updated()), this, SLOT(reject())); +} - connect(_dsoSig->get_device().get(), SIGNAL(device_updated()), this, SLOT(reject())); +void DsoMeasure::add_measure(QWidget *widget, const boost::shared_ptr dsoSig) +{ + const int Column = 5; + const int IconSizeForText = 5; + QGridLayout *layout = new QGridLayout(widget); + layout->setMargin(0); + layout->setSpacing(0); + for (int i=DSO_MS_BEGIN+1; isetProperty("id", QVariant(i)); + button->setIconSize(QSize(48, 48)); + QPixmap msPix(get_ms_icon(i)); + QBitmap msMask = msPix.createMaskFromColor(QColor("black"), Qt::MaskOutColor); + msPix.fill(dsoSig->get_colour()); + msPix.setMask(msMask); + button->setIcon(QIcon(msPix)); + layout->addWidget(button, + ((i-1)/Column)*IconSizeForText, (i-1)%Column, + IconSizeForText-1, 1, + Qt::AlignCenter); + layout->addWidget(new QLabel(get_ms_text(i), this), + ((i-1)/Column)*IconSizeForText+4, (i-1)%Column, + 1, 1, + Qt::AlignCenter); + layout->setColumnMinimumWidth((i-1)%Column, this->width()/Column); + + connect(button, SIGNAL(clicked()), this, SLOT(accept())); + } } void DsoMeasure::set_measure(bool en) @@ -67,21 +115,67 @@ void DsoMeasure::set_measure(bool en) QCheckBox* sc=dynamic_cast(sender()); if(sc != NULL) { QVariant id = sc->property("id"); - _dsoSig->set_ms_en(id.toInt(), sc->isChecked()); } } +QString DsoMeasure::get_ms_icon(int ms_type) +{ + assert(ms_type >= DSO_MS_BEGIN); + assert(ms_type < DSO_MS_END); + const QString icon_name[DSO_MS_END-DSO_MS_BEGIN] = {"blank.png", + "mFreq.png", "mPeriod.png", "mPduty.png", "mNduty.png", "mPcount.png", + "mRise.png", "mFall.png", "mPwidth.png", "mNwidth.png", "mBurst.png", + "mAmplitude.png", "mHigh.png", "mLow.png", "mRms.png", "mMean.png", + "mVpp.png", "mMax.png", "mMin.png", "mPover.png", "mNover.png"}; + return ":/icons/"+icon_name[ms_type]; +} + +QString DsoMeasure::get_ms_text(int ms_type) +{ + assert(ms_type >= DSO_MS_BEGIN); + assert(ms_type < DSO_MS_END); + const QString label_name[DSO_MS_END-DSO_MS_BEGIN] = {tr("NULL"), + tr("Freq"), tr("Period"), tr("+Duty"), tr("-Duty"), tr("+Count"), + tr("Rise"), tr("Fall"), tr("+Width"), tr("-Width"), tr("BrstW"), + tr("Ampl"), tr("High"), tr("Low"), tr("RMS"), tr("Mean"), + tr("PK-PK"), tr("Max"), tr("Min"), tr("+Over"), tr("-Over")}; + return label_name[ms_type]; +} + void DsoMeasure::accept() { using namespace Qt; - QDialog::accept(); + QToolButton* sc=dynamic_cast(sender()); + if(sc != NULL) { + QVariant id = sc->property("id"); + enum DSO_MEASURE_TYPE ms_type = DSO_MEASURE_TYPE(id.toInt()); + BOOST_FOREACH(const boost::shared_ptr s, _session.get_signals()) { + boost::shared_ptr dsoSig; + if ((dsoSig = dynamic_pointer_cast(s))) { + if (_measure_tab->currentWidget()->property("index").toInt() == dsoSig->get_index()) { + _view.get_viewstatus()->set_measure(_position, false, dsoSig->get_index(), ms_type); + break; + } + } + } + } + QDialog::accept(); } void DsoMeasure::reject() { using namespace Qt; + _view.get_viewstatus()->set_measure(_position, true, -1, DSO_MS_BEGIN); + QDialog::reject(); +} + +void DsoMeasure::reset() +{ + using namespace Qt; + + _view.get_viewstatus()->set_measure(_position, false, -1, DSO_MS_BEGIN); QDialog::reject(); } diff --git a/DSView/pv/dialogs/dsomeasure.h b/DSView/pv/dialogs/dsomeasure.h old mode 100644 new mode 100755 index a50689be0f0ffbf674ea424d50e65c2b4392fbbd..ab9c25ea6afbac9d0c14427a4a4bff56264dc6be --- a/DSView/pv/dialogs/dsomeasure.h +++ b/DSView/pv/dialogs/dsomeasure.h @@ -23,8 +23,10 @@ #ifndef DSVIEW_PV_DSOMEASURE_H #define DSVIEW_PV_DSOMEASURE_H -#include #include +#include +#include +#include #include @@ -34,8 +36,10 @@ namespace pv { +class SigSession; + namespace view { -class DsoSignal; +class View; } namespace dialogs { @@ -45,20 +49,33 @@ class DsoMeasure : public DSDialog Q_OBJECT public: - DsoMeasure(QWidget *parent, boost::shared_ptr dsoSig); + DsoMeasure(SigSession &session, view::View &parent, + unsigned int position, int last_sig_index); + + static QString get_ms_icon(int ms_type); + static QString get_ms_text(int ms_type); + +private: + void add_measure(QWidget *widget, const boost::shared_ptr dsoSig); private slots: void set_measure(bool en); + void reset(); protected: void accept(); void reject(); private: - boost::shared_ptr _dsoSig; + SigSession &_session; + view::View &_view; + unsigned int _position; + toolbars::TitleBar *_titlebar; - QVBoxLayout _layout; QDialogButtonBox _button_box; + QTabWidget *_measure_tab; + QVBoxLayout _layout; + std::vector _mbtn_vec; }; } // namespace dialogs diff --git a/DSView/pv/dialogs/fftoptions.cpp b/DSView/pv/dialogs/fftoptions.cpp old mode 100644 new mode 100755 index f3793b1acd5dce00e3dac009be2e990024f10f57..8fd495447c36bd397c9bd7772430558191f82d05 --- a/DSView/pv/dialogs/fftoptions.cpp +++ b/DSView/pv/dialogs/fftoptions.cpp @@ -27,10 +27,10 @@ #include #include "../sigsession.h" -#include "../data/mathstack.h" +#include "../data/spectrumstack.h" #include "../view/trace.h" #include "../view/dsosignal.h" -#include "../view/mathtrace.h" +#include "../view/spectrumtrace.h" using namespace boost; using namespace std; @@ -75,13 +75,13 @@ FftOptions::FftOptions(QWidget *parent, SigSession &session) : std::vector length; std::vector view_modes; std::vector dbv_ranges; - BOOST_FOREACH(const boost::shared_ptr t, _session.get_math_signals()) { - boost::shared_ptr mathTrace; - if ((mathTrace = dynamic_pointer_cast(t))) { - windows = mathTrace->get_math_stack()->get_windows_support(); - length = mathTrace->get_math_stack()->get_length_support(); - view_modes = mathTrace->get_view_modes_support(); - dbv_ranges = mathTrace->get_dbv_ranges(); + BOOST_FOREACH(const boost::shared_ptr t, _session.get_spectrum_traces()) { + boost::shared_ptr spectrumTraces; + if ((spectrumTraces = dynamic_pointer_cast(t))) { + windows = spectrumTraces->get_spectrum_stack()->get_windows_support(); + length = spectrumTraces->get_spectrum_stack()->get_length_support(); + view_modes = spectrumTraces->get_view_modes_support(); + dbv_ranges = spectrumTraces->get_dbv_ranges(); break; } } @@ -125,19 +125,19 @@ FftOptions::FftOptions(QWidget *parent, SigSession &session) : } // load current settings - BOOST_FOREACH(const boost::shared_ptr t, _session.get_math_signals()) { - boost::shared_ptr mathTrace; - if ((mathTrace = dynamic_pointer_cast(t))) { - if (mathTrace->enabled()) { + BOOST_FOREACH(const boost::shared_ptr t, _session.get_spectrum_traces()) { + boost::shared_ptr spectrumTraces; + if ((spectrumTraces = dynamic_pointer_cast(t))) { + if (spectrumTraces->enabled()) { _en_checkbox->setChecked(true); for (int i = 0; i < _ch_combobox->count(); i++) { - if (mathTrace->get_index() == _ch_combobox->itemData(i).toInt()) { + if (spectrumTraces->get_index() == _ch_combobox->itemData(i).toInt()) { _ch_combobox->setCurrentIndex(i); break; } } for (int i = 0; i < _len_combobox->count(); i++) { - if (mathTrace->get_math_stack()->get_sample_num() == _len_combobox->itemData(i).toULongLong()) { + if (spectrumTraces->get_spectrum_stack()->get_sample_num() == _len_combobox->itemData(i).toULongLong()) { _len_combobox->setCurrentIndex(i); break; } @@ -150,20 +150,20 @@ FftOptions::FftOptions(QWidget *parent, SigSession &session) : qVariantFromValue(i)); } for (int i = 0; i < _interval_combobox->count(); i++) { - if (mathTrace->get_math_stack()->get_sample_interval() == _interval_combobox->itemData(i).toInt()) { + if (spectrumTraces->get_spectrum_stack()->get_sample_interval() == _interval_combobox->itemData(i).toInt()) { _interval_combobox->setCurrentIndex(i); break; } } for (int i = 0; i < _dbv_combobox->count(); i++) { - if (mathTrace->dbv_range() == _dbv_combobox->itemData(i).toLongLong()) { + if (spectrumTraces->dbv_range() == _dbv_combobox->itemData(i).toLongLong()) { _dbv_combobox->setCurrentIndex(i); break; } } - _window_combobox->setCurrentIndex(mathTrace->get_math_stack()->get_windows_index()); - _dc_checkbox->setChecked(mathTrace->get_math_stack()->dc_ignored()); - _view_combobox->setCurrentIndex(mathTrace->view_mode()); + _window_combobox->setCurrentIndex(spectrumTraces->get_spectrum_stack()->get_windows_index()); + _dc_checkbox->setChecked(spectrumTraces->get_spectrum_stack()->dc_ignored()); + _view_combobox->setCurrentIndex(spectrumTraces->view_mode()); } } } @@ -214,26 +214,26 @@ void FftOptions::accept() QDialog::accept(); - BOOST_FOREACH(const boost::shared_ptr t, _session.get_math_signals()) { - boost::shared_ptr mathTrace; - if ((mathTrace = dynamic_pointer_cast(t))) { - mathTrace->set_enable(false); - if (mathTrace->get_index() == _ch_combobox->currentData().toInt()) { - mathTrace->get_math_stack()->set_dc_ignore(_dc_checkbox->isChecked()); - mathTrace->get_math_stack()->set_sample_num(_len_combobox->currentData().toULongLong()); - mathTrace->get_math_stack()->set_sample_interval(_interval_combobox->currentData().toInt()); - mathTrace->get_math_stack()->set_windows_index(_window_combobox->currentData().toInt()); - mathTrace->set_view_mode(_view_combobox->currentData().toUInt()); - //mathTrace->init_zoom(); - mathTrace->set_dbv_range(_dbv_combobox->currentData().toInt()); - mathTrace->set_enable(_en_checkbox->isChecked()); + BOOST_FOREACH(const boost::shared_ptr t, _session.get_spectrum_traces()) { + boost::shared_ptr spectrumTraces; + if ((spectrumTraces = dynamic_pointer_cast(t))) { + spectrumTraces->set_enable(false); + if (spectrumTraces->get_index() == _ch_combobox->currentData().toInt()) { + spectrumTraces->get_spectrum_stack()->set_dc_ignore(_dc_checkbox->isChecked()); + spectrumTraces->get_spectrum_stack()->set_sample_num(_len_combobox->currentData().toULongLong()); + spectrumTraces->get_spectrum_stack()->set_sample_interval(_interval_combobox->currentData().toInt()); + spectrumTraces->get_spectrum_stack()->set_windows_index(_window_combobox->currentData().toInt()); + spectrumTraces->set_view_mode(_view_combobox->currentData().toUInt()); + //spectrumTraces->init_zoom(); + spectrumTraces->set_dbv_range(_dbv_combobox->currentData().toInt()); + spectrumTraces->set_enable(_en_checkbox->isChecked()); if (_session.get_capture_state() == SigSession::Stopped && - mathTrace->enabled()) - mathTrace->get_math_stack()->calc_fft(); + spectrumTraces->enabled()) + spectrumTraces->get_spectrum_stack()->calc_fft(); } } } - _session.mathTraces_rebuild(); + _session.spectrum_rebuild(); } void FftOptions::reject() diff --git a/DSView/pv/dialogs/fftoptions.h b/DSView/pv/dialogs/fftoptions.h old mode 100644 new mode 100755 diff --git a/DSView/pv/dialogs/interval.cpp b/DSView/pv/dialogs/interval.cpp old mode 100644 new mode 100755 diff --git a/DSView/pv/dialogs/interval.h b/DSView/pv/dialogs/interval.h old mode 100644 new mode 100755 diff --git a/DSView/pv/dialogs/lissajousoptions.cpp b/DSView/pv/dialogs/lissajousoptions.cpp new file mode 100755 index 0000000000000000000000000000000000000000..8bc54fcd1370bff56b0dc9b97a7e2c9704c0cb4d --- /dev/null +++ b/DSView/pv/dialogs/lissajousoptions.cpp @@ -0,0 +1,197 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2015 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "lissajousoptions.h" +#include "../device/devinst.h" +#include "../sigsession.h" +#include "../view/view.h" +#include "../view/lissajoustrace.h" + +#include +#include +#include +#include +#include + +#include + +using namespace boost; +using namespace std; +using namespace pv::view; + +namespace pv { +namespace dialogs { + +LissajousOptions::LissajousOptions(SigSession &session, QWidget *parent) : + DSDialog(parent), + _session(session), + _button_box(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, + Qt::Horizontal, this) +{ + setMinimumSize(300, 300); + + _enable = new QCheckBox(this); + + QLabel *lisa_label = new QLabel(this); + lisa_label->setPixmap(QPixmap(":/icons/lissajous.png")); + + _percent = new QSlider(Qt::Horizontal, this); + _percent->setRange(100, 100); + _percent->setEnabled(false); + if (_session.cur_samplelimits() > WellLen) { + int min = WellLen*100.0/_session.cur_samplelimits(); + _percent->setEnabled(true); + _percent->setRange(min, 100); + _percent->setValue(min); + } + + _x_group = new QGroupBox(this); + _y_group = new QGroupBox(this); + QHBoxLayout *xlayout = new QHBoxLayout(); + QHBoxLayout *ylayout = new QHBoxLayout(); + BOOST_FOREACH(const boost::shared_ptr s, _session.get_signals()) { + boost::shared_ptr dsoSig; + if ((dsoSig = dynamic_pointer_cast(s))) { + QString index_str = QString::number(dsoSig->get_index()); + QRadioButton *xradio = new QRadioButton(index_str, _x_group); + xradio->setProperty("index", dsoSig->get_index()); + xlayout->addWidget(xradio); + QRadioButton *yradio = new QRadioButton(index_str, _y_group); + yradio->setProperty("index", dsoSig->get_index()); + ylayout->addWidget(yradio); + _x_radio.append(xradio); + _y_radio.append(yradio); + } + } + _x_group->setLayout(xlayout); + _y_group->setLayout(ylayout); + + + boost::shared_ptr lissajous = _session.get_lissajous_trace(); + if (lissajous) { + _enable->setChecked(lissajous->enabled()); + _percent->setValue(lissajous->percent()); + for (QVector::const_iterator i = _x_radio.begin(); + i != _x_radio.end(); i++) { + if ((*i)->property("index").toInt() == lissajous->xIndex()) { + (*i)->setChecked(true); + break; + } + } + for (QVector::const_iterator i = _y_radio.begin(); + i != _y_radio.end(); i++) { + if ((*i)->property("index").toInt() == lissajous->yIndex()) { + (*i)->setChecked(true); + break; + } + } + } else { + _enable->setChecked(false); + for (QVector::const_iterator i = _x_radio.begin(); + i != _x_radio.end(); i++) { + (*i)->setChecked(true); + break; + } + for (QVector::const_iterator i = _y_radio.begin(); + i != _y_radio.end(); i++) { + (*i)->setChecked(true); + break; + } + } + + _layout = new QGridLayout(); + _layout->setMargin(0); + _layout->setSpacing(0); + _layout->addWidget(lisa_label, 0, 0, 1, 2, Qt::AlignCenter); + _layout->addWidget(_enable, 1, 0, 1, 1); + _layout->addWidget(_percent, 2, 0, 1, 2); + _layout->addWidget(_x_group, 3, 0, 1, 1); + _layout->addWidget(_y_group, 3, 1, 1, 1); + _layout->addWidget(new QLabel(this), 4, 1, 1, 1); + _layout->addWidget(&_button_box, 5, 1, 1, 1, Qt::AlignHCenter | Qt::AlignBottom); + + layout()->addLayout(_layout); + + connect(&_button_box, SIGNAL(rejected()), this, SLOT(reject())); + connect(&_button_box, SIGNAL(accepted()), this, SLOT(accept())); + + retranslateUi(); +} + +void LissajousOptions::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + retranslateUi(); + DSDialog::changeEvent(event); +} + +void LissajousOptions::retranslateUi() +{ + _enable->setText(tr("Enable")); + _x_group->setTitle(tr("X-axis")); + _y_group->setTitle(tr("Y-axis")); + setTitle(tr("Lissajous Options")); +} + +void LissajousOptions::accept() +{ + using namespace Qt; + QDialog::accept(); + + int xindex = -1; + int yindex = -1; + for (QVector::const_iterator i = _x_radio.begin(); + i != _x_radio.end(); i++) { + if ((*i)->isChecked()) { + xindex = (*i)->property("index").toInt(); + break; + } + } + for (QVector::const_iterator i = _y_radio.begin(); + i != _y_radio.end(); i++) { + if ((*i)->isChecked()) { + yindex = (*i)->property("index").toInt(); + break; + } + } + bool enable = (xindex != -1 && yindex != -1 && _enable->isChecked()); + _session.lissajous_rebuild(enable, xindex, yindex, _percent->value()); + + BOOST_FOREACH(const boost::shared_ptr s, _session.get_signals()) { + boost::shared_ptr dsoSig; + if ((dsoSig = dynamic_pointer_cast(s))) { + dsoSig->set_show(!enable); + } + } + boost::shared_ptr mathTrace = _session.get_math_trace(); + if (mathTrace && mathTrace->enabled()) { + mathTrace->set_show(!enable); + } +} + +void LissajousOptions::reject() +{ + using namespace Qt; + QDialog::reject(); +} + +} // namespace dialogs +} // namespace pv diff --git a/DSView/pv/dialogs/lissajousoptions.h b/DSView/pv/dialogs/lissajousoptions.h new file mode 100755 index 0000000000000000000000000000000000000000..b3fd13f1e353691a6cf451a406f1465ce35f5f09 --- /dev/null +++ b/DSView/pv/dialogs/lissajousoptions.h @@ -0,0 +1,85 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2015 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef DSVIEW_PV_LISSAJOUSOPTIONS_H +#define DSVIEW_PV_LISSAJOUSOPTIONS_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../view/dsosignal.h" +#include "../toolbars/titlebar.h" +#include "dsdialog.h" + +namespace pv { + +class SigSession; + +namespace view { +class View; +} + +namespace dialogs { + +class LissajousOptions : public DSDialog +{ + Q_OBJECT + +private: + static const int WellLen = SR_Kn(16); + +public: + LissajousOptions(SigSession &session, QWidget *parent); + +private: + void changeEvent(QEvent *event); + void retranslateUi(); + +protected: + void accept(); + void reject(); + +private: + SigSession &_session; + + QCheckBox *_enable; + QGroupBox *_x_group; + QGroupBox *_y_group; + QSlider *_percent; + QVector _x_radio; + QVector _y_radio; + QDialogButtonBox _button_box; + QGridLayout *_layout; +}; + +} // namespace dialogs +} // namespace pv + +#endif // DSVIEW_PV_LISSAJOUSOPTIONS_H diff --git a/DSView/pv/dialogs/mathoptions.cpp b/DSView/pv/dialogs/mathoptions.cpp new file mode 100755 index 0000000000000000000000000000000000000000..f41b9e261319fb1494d1bd577a85ef0430769e12 --- /dev/null +++ b/DSView/pv/dialogs/mathoptions.cpp @@ -0,0 +1,228 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2015 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "mathoptions.h" +#include "../device/devinst.h" +#include "../sigsession.h" +#include "../view/view.h" +#include "../view/mathtrace.h" +#include "../data/mathstack.h" + +#include +#include +#include +#include +#include + +#include + +using namespace boost; +using namespace std; +using namespace pv::view; + +namespace pv { +namespace dialogs { + +MathOptions::MathOptions(SigSession &session, QWidget *parent) : + DSDialog(parent), + _session(session), + _button_box(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, + Qt::Horizontal, this) +{ + setMinimumSize(300, 300); + + _enable = new QCheckBox(this); + + QLabel *lisa_label = new QLabel(this); + lisa_label->setPixmap(QPixmap(":/icons/math.png")); + + _math_group = new QGroupBox(this); + QHBoxLayout *type_layout = new QHBoxLayout(); + QRadioButton *add_radio = new QRadioButton(tr("Add"), _math_group); + add_radio->setProperty("type", data::MathStack::MATH_ADD); + type_layout->addWidget(add_radio); + QRadioButton *sub_radio = new QRadioButton(tr("Substract"), _math_group); + sub_radio->setProperty("type", data::MathStack::MATH_SUB); + type_layout->addWidget(sub_radio); + QRadioButton *mul_radio = new QRadioButton(tr("Multiply"), _math_group); + mul_radio->setProperty("type", data::MathStack::MATH_MUL); + type_layout->addWidget(mul_radio); + QRadioButton *div_radio = new QRadioButton(tr("Divide"), _math_group); + div_radio->setProperty("type", data::MathStack::MATH_DIV); + type_layout->addWidget(div_radio); + _math_radio.append(add_radio); + _math_radio.append(sub_radio); + _math_radio.append(mul_radio); + _math_radio.append(div_radio); + _math_group->setLayout(type_layout); + + _src1_group = new QGroupBox(this); + _src2_group = new QGroupBox(this); + QHBoxLayout *src1_layout = new QHBoxLayout(); + QHBoxLayout *src2_layout = new QHBoxLayout(); + BOOST_FOREACH(const boost::shared_ptr s, _session.get_signals()) { + boost::shared_ptr dsoSig; + if ((dsoSig = dynamic_pointer_cast(s))) { + QString index_str = QString::number(dsoSig->get_index()); + QRadioButton *xradio = new QRadioButton(index_str, _src1_group); + xradio->setProperty("index", dsoSig->get_index()); + src1_layout->addWidget(xradio); + QRadioButton *yradio = new QRadioButton(index_str, _src2_group); + yradio->setProperty("index", dsoSig->get_index()); + src2_layout->addWidget(yradio); + _src1_radio.append(xradio); + _src2_radio.append(yradio); + } + } + _src1_group->setLayout(src1_layout); + _src2_group->setLayout(src2_layout); + + + boost::shared_ptr math = _session.get_math_trace(); + if (math) { + _enable->setChecked(math->enabled()); + for (QVector::const_iterator i = _src1_radio.begin(); + i != _src1_radio.end(); i++) { + if ((*i)->property("index").toInt() == math->src1()) { + (*i)->setChecked(true); + break; + } + } + for (QVector::const_iterator i = _src2_radio.begin(); + i != _src2_radio.end(); i++) { + if ((*i)->property("index").toInt() == math->src2()) { + (*i)->setChecked(true); + break; + } + } + for (QVector::const_iterator i = _math_radio.begin(); + i != _math_radio.end(); i++) { + if ((*i)->property("type").toInt() == math->get_math_stack()->get_type()) { + (*i)->setChecked(true); + break; + } + } + } else { + _enable->setChecked(false); + for (QVector::const_iterator i = _src1_radio.begin(); + i != _src1_radio.end(); i++) { + (*i)->setChecked(true); + break; + } + for (QVector::const_iterator i = _src2_radio.begin(); + i != _src2_radio.end(); i++) { + (*i)->setChecked(true); + break; + } + for (QVector::const_iterator i = _math_radio.begin(); + i != _math_radio.end(); i++) { + (*i)->setChecked(true); + break; + } + } + + _layout = new QGridLayout(); + _layout->setMargin(0); + _layout->setSpacing(0); + _layout->addWidget(lisa_label, 0, 0, 1, 2, Qt::AlignCenter); + _layout->addWidget(_enable, 1, 0, 1, 1); + _layout->addWidget(_math_group, 2, 0, 1, 2); + _layout->addWidget(_src1_group, 3, 0, 1, 1); + _layout->addWidget(_src2_group, 3, 1, 1, 1); + _layout->addWidget(new QLabel(this), 4, 1, 1, 1); + _layout->addWidget(&_button_box, 5, 1, 1, 1, Qt::AlignHCenter | Qt::AlignBottom); + + layout()->addLayout(_layout); + + connect(&_button_box, SIGNAL(rejected()), this, SLOT(reject())); + connect(&_button_box, SIGNAL(accepted()), this, SLOT(accept())); + + retranslateUi(); +} + +void MathOptions::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + retranslateUi(); + DSDialog::changeEvent(event); +} + +void MathOptions::retranslateUi() +{ + _enable->setText(tr("Enable")); + _math_group->setTitle(tr("Math Type")); + _src1_group->setTitle(tr("1st Source")); + _src2_group->setTitle(tr("2nd Source")); + setTitle(tr("Math Options")); +} + +void MathOptions::accept() +{ + using namespace Qt; + QDialog::accept(); + + int src1 = -1; + int src2 = -1; + data::MathStack::MathType type = data::MathStack::MATH_ADD; + for (QVector::const_iterator i = _src1_radio.begin(); + i != _src1_radio.end(); i++) { + if ((*i)->isChecked()) { + src1 = (*i)->property("index").toInt(); + break; + } + } + for (QVector::const_iterator i = _src2_radio.begin(); + i != _src2_radio.end(); i++) { + if ((*i)->isChecked()) { + src2 = (*i)->property("index").toInt(); + break; + } + } + for (QVector::const_iterator i = _math_radio.begin(); + i != _math_radio.end(); i++) { + if ((*i)->isChecked()) { + type = (data::MathStack::MathType)(*i)->property("type").toInt(); + break; + } + } + bool enable = (src1 != -1 && src2 != -1 && _enable->isChecked()); + boost::shared_ptr dsoSig1; + boost::shared_ptr dsoSig2; + BOOST_FOREACH(const boost::shared_ptr s, _session.get_signals()) { + boost::shared_ptr dsoSig; + if ((dsoSig = dynamic_pointer_cast(s))) { + if (dsoSig->get_index() == src1) + dsoSig1 = dsoSig; + if (dsoSig->get_index() == src2) + dsoSig2 = dsoSig; + } + } + _session.math_rebuild(enable, dsoSig1, dsoSig2, type); +} + +void MathOptions::reject() +{ + using namespace Qt; + QDialog::reject(); +} + +} // namespace dialogs +} // namespace pv diff --git a/DSView/pv/dialogs/mathoptions.h b/DSView/pv/dialogs/mathoptions.h new file mode 100755 index 0000000000000000000000000000000000000000..d11afa36a8f0787ba12e2f9e20ac8330f5f745b8 --- /dev/null +++ b/DSView/pv/dialogs/mathoptions.h @@ -0,0 +1,86 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2015 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef DSVIEW_PV_MATHOPTIONS_H +#define DSVIEW_PV_MATHOPTIONS_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../view/dsosignal.h" +#include "../toolbars/titlebar.h" +#include "dsdialog.h" + +namespace pv { + +class SigSession; + +namespace view { +class View; +} + +namespace dialogs { + +class MathOptions : public DSDialog +{ + Q_OBJECT + +private: + static const int WellLen = SR_Kn(16); + +public: + MathOptions(SigSession &session, QWidget *parent); + +private: + void changeEvent(QEvent *event); + void retranslateUi(); + +protected: + void accept(); + void reject(); + +private: + SigSession &_session; + + QCheckBox *_enable; + QGroupBox *_src1_group; + QGroupBox *_src2_group; + QGroupBox *_math_group; + QVector _src1_radio; + QVector _src2_radio; + QVector _math_radio; + QDialogButtonBox _button_box; + QGridLayout *_layout; +}; + +} // namespace dialogs +} // namespace pv + +#endif // DSVIEW_PV_MATHOPTIONS_H diff --git a/DSView/pv/dialogs/protocolexp.cpp b/DSView/pv/dialogs/protocolexp.cpp old mode 100644 new mode 100755 index 04be836ba4bc8790d2b8b04a61fb9b575655623b..dce4d33e551b376d834f64a71e570f0a6042822b --- a/DSView/pv/dialogs/protocolexp.cpp +++ b/DSView/pv/dialogs/protocolexp.cpp @@ -23,6 +23,7 @@ #include +#include #include #include #include @@ -118,7 +119,7 @@ void ProtocolExp::accept() filter.append(";;"); } const QString DIR_KEY("ProtocolExportPath"); - QSettings settings; + QSettings settings(QApplication::organizationName(), QApplication::applicationName()); QString default_filter = _format_combobox->currentText(); QString file_name = QFileDialog::getSaveFileName( this, tr("Export Data"), settings.value(DIR_KEY).toString(),filter,&default_filter); @@ -136,7 +137,7 @@ void ProtocolExp::accept() file.open(QIODevice::WriteOnly | QIODevice::Text); QTextStream out(&file); out.setCodec("UTF-8"); - out.setGenerateByteOrderMark(true); + //out.setGenerateByteOrderMark(true); // UTF-8 without BOM QFuture future; future = QtConcurrent::run([&]{ diff --git a/DSView/pv/dialogs/protocolexp.h b/DSView/pv/dialogs/protocolexp.h old mode 100644 new mode 100755 diff --git a/DSView/pv/dialogs/protocollist.cpp b/DSView/pv/dialogs/protocollist.cpp old mode 100644 new mode 100755 diff --git a/DSView/pv/dialogs/protocollist.h b/DSView/pv/dialogs/protocollist.h old mode 100644 new mode 100755 diff --git a/DSView/pv/dialogs/regionoptions.cpp b/DSView/pv/dialogs/regionoptions.cpp new file mode 100755 index 0000000000000000000000000000000000000000..0a1131332929013dbb48d463e7a3c2b1e1610270 --- /dev/null +++ b/DSView/pv/dialogs/regionoptions.cpp @@ -0,0 +1,115 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2016 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "regionoptions.h" + +#include + +#include "../sigsession.h" +#include "../view/cursor.h" +#include "../view/view.h" +#include "../device/devinst.h" + +using namespace boost; +using namespace std; + +namespace pv { +namespace dialogs { + +const QString RegionOptions::RegionStart = QT_TR_NOOP("Start"); +const QString RegionOptions::RegionEnd = QT_TR_NOOP("End"); + +RegionOptions::RegionOptions(view::View *view, SigSession &session, QWidget *parent) : + DSDialog(parent), + _session(session), + _view(view), + _button_box(QDialogButtonBox::Ok, + Qt::Horizontal, this) +{ + QHBoxLayout *hlayout = new QHBoxLayout(); + hlayout->setMargin(0); + hlayout->setSpacing(0); + _start_comboBox = new QComboBox(this); + _end_comboBox = new QComboBox(this); + _start_comboBox->addItem(RegionStart); + _end_comboBox->addItem(RegionEnd); + if (_view) { + int index = 1; + for(std::list::iterator i = _view->get_cursorList().begin(); + i != _view->get_cursorList().end(); i++) { + QString curCursor = tr("Cursor ")+QString::number(index); + _start_comboBox->addItem(curCursor); + _end_comboBox->addItem(curCursor); + index++; + } + } + hlayout->addWidget(new QLabel("Start: ", this)); + hlayout->addWidget(_start_comboBox); + hlayout->addWidget(new QLabel(" ", this)); + hlayout->addWidget(new QLabel("End: ", this)); + hlayout->addWidget(_end_comboBox); + + QVBoxLayout *vlayout = new QVBoxLayout(); + vlayout->addLayout(hlayout); + vlayout->addWidget(&_button_box); + + layout()->addLayout(vlayout); + setTitle(tr("Region")); + + connect(&_button_box, SIGNAL(accepted()), this, SLOT(set_region())); + connect(_session.get_device().get(), SIGNAL(device_updated()), this, SLOT(reject())); + +} + +void RegionOptions::set_region() +{ + const uint64_t last_samples = _session.cur_samplelimits() - 1; + const int index1 = _start_comboBox->currentIndex(); + const int index2 = _end_comboBox->currentIndex(); + uint64_t start, end; + + _session.set_save_start(0); + _session.set_save_end(last_samples); + + if (index1 == 0) { + start = 0; + } else { + start = _view->get_cursor_samples(index1-1); + } + if (index2 == 0) { + end = last_samples; + } else { + end = _view->get_cursor_samples(index2-1); + } + + if (start > last_samples) + start = 0; + if (end > last_samples) + end = last_samples; + + _session.set_save_start(min(start, end)); + _session.set_save_end(max(start, end)); + + QDialog::accept(); +} + +} // namespace dialogs +} // namespace pv diff --git a/DSView/pv/dialogs/regionoptions.h b/DSView/pv/dialogs/regionoptions.h new file mode 100755 index 0000000000000000000000000000000000000000..097baff7575e077b9eb8c4a702192479bc1bebc5 --- /dev/null +++ b/DSView/pv/dialogs/regionoptions.h @@ -0,0 +1,74 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2016 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef DSVIEW_PV_REGIONOPTIONS_H +#define DSVIEW_PV_REGIONOPTIONS_H + +#include +#include +#include +#include +#include + +#include + +#include "../toolbars/titlebar.h" +#include "dsdialog.h" + +namespace pv { + +class SigSession; + +namespace view { +class View; +} + +namespace dialogs { + +class RegionOptions : public DSDialog +{ + Q_OBJECT +private: + static const QString RegionStart; + static const QString RegionEnd; + +public: + RegionOptions(view::View *view, SigSession &session, QWidget *parent = 0); + +private slots: + void set_region(); + +private: + SigSession &_session; + view::View *_view; + + QComboBox *_start_comboBox; + QComboBox *_end_comboBox; + + QDialogButtonBox _button_box; + +}; + +} // namespace dialogs +} // namespace pv + +#endif // DSVIEW_PV_REGIONOPTIONS_H diff --git a/DSView/pv/dialogs/search.cpp b/DSView/pv/dialogs/search.cpp old mode 100644 new mode 100755 index 06b029e100f5be59ec0ab25e734c8b42b2a23460..86e69ddabc26845a81bb2aa1c70dbb0298e80722 --- a/DSView/pv/dialogs/search.cpp +++ b/DSView/pv/dialogs/search.cpp @@ -1,128 +1,128 @@ -/* - * This file is part of the DSView project. - * DSView is based on PulseView. - * - * Copyright (C) 2013 DreamSourceLab - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "search.h" -#include "../view/logicsignal.h" - -#include -#include - -#include - -namespace pv { -namespace dialogs { - -Search::Search(QWidget *parent, SigSession &session, std::map pattern) : - DSDialog(parent), - _session(session) -{ - - QFont font("Monaco"); - font.setStyleHint(QFont::Monospace); - font.setFixedPitch(true); - //this->setMinimumWidth(350); - - QRegExp value_rx("[10XRFCxrfc]+"); - QValidator *value_validator = new QRegExpValidator(value_rx, this); - - search_buttonBox.addButton(QDialogButtonBox::Ok); - search_buttonBox.addButton(QDialogButtonBox::Cancel); - - QGridLayout *search_layout = new QGridLayout(); - search_layout->setVerticalSpacing(0); - - int index = 0; - BOOST_FOREACH(const boost::shared_ptr sig, - _session.get_signals()) { - assert(sig); - boost::shared_ptr logic_sig; - if ((logic_sig = boost::dynamic_pointer_cast(sig))) { - QLineEdit *search_lineEdit = new QLineEdit(this); - if (pattern.find(logic_sig->get_index()) != pattern.end()) - search_lineEdit->setText(pattern[logic_sig->get_index()]); - else - search_lineEdit->setText("X"); - search_lineEdit->setValidator(value_validator); - search_lineEdit->setMaxLength(1); - search_lineEdit->setInputMask("X"); - search_lineEdit->setFont(font); - _search_lineEdit_vec.push_back(search_lineEdit); - - search_layout->addWidget(new QLabel(logic_sig->get_name()+":"), index, 0, Qt::AlignRight); - search_layout->addWidget(new QLabel(QString::number(logic_sig->get_index())), index, 1, Qt::AlignRight); - search_layout->addWidget(search_lineEdit, index, 2); - - connect(search_lineEdit, SIGNAL(editingFinished()), this, SLOT(format())); - - index++; - } - } - - search_layout->addWidget(new QLabel(" "), index,0); - search_layout->addWidget(new QLabel(tr("X: Don't care\n0: Low level\n1: High level\nR: Rising edge\nF: Falling edge\nC: Rising/Falling edge")), 0, 3, index, 1); - search_layout->addWidget(&search_buttonBox, index+1, 3); - search_layout->setColumnStretch(3, 100); - - layout()->addLayout(search_layout); - setTitle(tr("Search Options")); - - connect(&search_buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(&search_buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - connect(_session.get_device().get(), SIGNAL(device_updated()), this, SLOT(reject())); -} - -Search::~Search() -{ -} - -void Search::accept() -{ - using namespace Qt; - - QDialog::accept(); -} - -void Search::format() -{ - QLineEdit *sc = qobject_cast(sender()); - sc->setText(sc->text().toUpper()); -} - -std::map Search::get_pattern() -{ - std::map pattern; - - int index = 0; - BOOST_FOREACH(const boost::shared_ptr sig, - _session.get_signals()) { - assert(sig); - boost::shared_ptr logic_sig; - if ((logic_sig = boost::dynamic_pointer_cast(sig))) { - pattern[logic_sig->get_index()] = _search_lineEdit_vec[index]->text(); - index++; - } - } - - return pattern; -} - -} // namespace decoder -} // namespace pv +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2013 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "search.h" +#include "../view/logicsignal.h" + +#include +#include + +#include + +namespace pv { +namespace dialogs { + +Search::Search(QWidget *parent, SigSession &session, std::map pattern) : + DSDialog(parent), + _session(session) +{ + + QFont font("Monaco"); + font.setStyleHint(QFont::Monospace); + font.setFixedPitch(true); + //this->setMinimumWidth(350); + + QRegExp value_rx("[10XRFCxrfc]+"); + QValidator *value_validator = new QRegExpValidator(value_rx, this); + + search_buttonBox.addButton(QDialogButtonBox::Ok); + search_buttonBox.addButton(QDialogButtonBox::Cancel); + + QGridLayout *search_layout = new QGridLayout(); + search_layout->setVerticalSpacing(0); + + int index = 0; + BOOST_FOREACH(const boost::shared_ptr sig, + _session.get_signals()) { + assert(sig); + boost::shared_ptr logic_sig; + if ((logic_sig = boost::dynamic_pointer_cast(sig))) { + QLineEdit *search_lineEdit = new QLineEdit(this); + if (pattern.find(logic_sig->get_index()) != pattern.end()) + search_lineEdit->setText(pattern[logic_sig->get_index()]); + else + search_lineEdit->setText("X"); + search_lineEdit->setValidator(value_validator); + search_lineEdit->setMaxLength(1); + search_lineEdit->setInputMask("X"); + search_lineEdit->setFont(font); + _search_lineEdit_vec.push_back(search_lineEdit); + + search_layout->addWidget(new QLabel(logic_sig->get_name()+":"), index, 0, Qt::AlignRight); + search_layout->addWidget(new QLabel(QString::number(logic_sig->get_index())), index, 1, Qt::AlignRight); + search_layout->addWidget(search_lineEdit, index, 2); + + connect(search_lineEdit, SIGNAL(editingFinished()), this, SLOT(format())); + + index++; + } + } + + search_layout->addWidget(new QLabel(" "), index,0); + search_layout->addWidget(new QLabel(tr("X: Don't care\n0: Low level\n1: High level\nR: Rising edge\nF: Falling edge\nC: Rising/Falling edge")), 0, 3, index, 1); + search_layout->addWidget(&search_buttonBox, index+1, 3); + search_layout->setColumnStretch(3, 100); + + layout()->addLayout(search_layout); + setTitle(tr("Search Options")); + + connect(&search_buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(&search_buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + connect(_session.get_device().get(), SIGNAL(device_updated()), this, SLOT(reject())); +} + +Search::~Search() +{ +} + +void Search::accept() +{ + using namespace Qt; + + QDialog::accept(); +} + +void Search::format() +{ + QLineEdit *sc = qobject_cast(sender()); + sc->setText(sc->text().toUpper()); +} + +std::map Search::get_pattern() +{ + std::map pattern; + + int index = 0; + BOOST_FOREACH(const boost::shared_ptr sig, + _session.get_signals()) { + assert(sig); + boost::shared_ptr logic_sig; + if ((logic_sig = boost::dynamic_pointer_cast(sig))) { + pattern[logic_sig->get_index()] = _search_lineEdit_vec[index]->text(); + index++; + } + } + + return pattern; +} + +} // namespace decoder +} // namespace pv diff --git a/DSView/pv/dialogs/search.h b/DSView/pv/dialogs/search.h old mode 100644 new mode 100755 index 31e965ef7e2c5c4705bbed9c2a122b6bdaf18481..d1f7950aa85d5fe80fea4b16a273c5521f4c58f4 --- a/DSView/pv/dialogs/search.h +++ b/DSView/pv/dialogs/search.h @@ -1,72 +1,72 @@ -/* - * This file is part of the DSView project. - * DSView is based on PulseView. - * - * Copyright (C) 2013 DreamSourceLab - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#ifndef DSVIEW_PV_SEARCH_H -#define DSVIEW_PV_SEARCH_H - -#include -#include -#include -#include -#include - -#include "../sigsession.h" -#include "../toolbars/titlebar.h" -#include "dsdialog.h" -#include "../device/devinst.h" - -#include - -namespace pv { -namespace dialogs { - -class Search : public DSDialog -{ - Q_OBJECT - -public: - - Search(QWidget *parent, SigSession &session, std::map pattern); - ~Search(); - - std::map get_pattern(); - -protected: - void accept(); - -signals: - -private slots: - void format(); - -private: - SigSession &_session; - - toolbars::TitleBar *_titlebar; - QVector _search_lineEdit_vec; - QDialogButtonBox search_buttonBox; -}; - -} // namespace decoder -} // namespace pv - -#endif // DSVIEW_PV_SEARCH_H +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2013 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef DSVIEW_PV_SEARCH_H +#define DSVIEW_PV_SEARCH_H + +#include +#include +#include +#include +#include + +#include "../sigsession.h" +#include "../toolbars/titlebar.h" +#include "dsdialog.h" +#include "../device/devinst.h" + +#include + +namespace pv { +namespace dialogs { + +class Search : public DSDialog +{ + Q_OBJECT + +public: + + Search(QWidget *parent, SigSession &session, std::map pattern); + ~Search(); + + std::map get_pattern(); + +protected: + void accept(); + +signals: + +private slots: + void format(); + +private: + SigSession &_session; + + toolbars::TitleBar *_titlebar; + QVector _search_lineEdit_vec; + QDialogButtonBox search_buttonBox; +}; + +} // namespace decoder +} // namespace pv + +#endif // DSVIEW_PV_SEARCH_H diff --git a/DSView/pv/dialogs/shadow.cpp b/DSView/pv/dialogs/shadow.cpp old mode 100644 new mode 100755 diff --git a/DSView/pv/dialogs/shadow.h b/DSView/pv/dialogs/shadow.h old mode 100644 new mode 100755 diff --git a/DSView/pv/dialogs/storeprogress.cpp b/DSView/pv/dialogs/storeprogress.cpp old mode 100644 new mode 100755 index fc01b21735ecef464c9eac40f140fc3a9ba54827..ac84b808d8e26357c8dd552fbaa2369667d9eec3 --- a/DSView/pv/dialogs/storeprogress.cpp +++ b/DSView/pv/dialogs/storeprogress.cpp @@ -70,10 +70,10 @@ void StoreProgress::timeout() QTimer::singleShot(100, this, SLOT(timeout())); } -void StoreProgress::save_run() +void StoreProgress::save_run(QString session_file) { - _info.setText("Saving..."); - if (_store_session.save_start()) + _info.setText(tr("Saving...")); + if (_store_session.save_start(session_file)) show(); else show_error(); @@ -83,7 +83,7 @@ void StoreProgress::save_run() void StoreProgress::export_run() { - _info.setText("Exporting..."); + _info.setText(tr("Exporting...")); if (_store_session.export_start()) show(); else diff --git a/DSView/pv/dialogs/storeprogress.h b/DSView/pv/dialogs/storeprogress.h old mode 100644 new mode 100755 index 30cfc841f36c89a2fa7cde51ffabdfca1a0716e5..28cf5cb3d76a70b7bff42298200b4da49a97d735 --- a/DSView/pv/dialogs/storeprogress.h +++ b/DSView/pv/dialogs/storeprogress.h @@ -61,7 +61,7 @@ private: void closeEvent(QCloseEvent* e); public slots: - void save_run(); + void save_run(QString session_file); void export_run(); private slots: diff --git a/DSView/pv/dialogs/waitingdialog.cpp b/DSView/pv/dialogs/waitingdialog.cpp old mode 100644 new mode 100755 index ee89d2ff6825b20debd309774863b83f1e0fa99c..f3d77fca5c55ce9390106fda85946f1a323caa24 --- a/DSView/pv/dialogs/waitingdialog.cpp +++ b/DSView/pv/dialogs/waitingdialog.cpp @@ -41,8 +41,9 @@ namespace dialogs { const QString WaitingDialog::TIPS_WAIT = QT_TR_NOOP("Waiting"); const QString WaitingDialog::TIPS_FINISHED = QT_TR_NOOP("Finished!"); -WaitingDialog::WaitingDialog(QWidget *parent, boost::shared_ptr dev_inst) : +WaitingDialog::WaitingDialog(QWidget *parent, boost::shared_ptr dev_inst, int key) : DSDialog(parent), + _key(key), _dev_inst(dev_inst), _button_box(QDialogButtonBox::Abort, Qt::Horizontal, this) @@ -50,8 +51,9 @@ WaitingDialog::WaitingDialog(QWidget *parent, boost::shared_ptrsetFixedSize((GIF_WIDTH+TIP_WIDTH)*1.2, (GIF_HEIGHT+TIP_HEIGHT)*4); this->setWindowOpacity(0.7); + QString iconPath = ":/icons/" + qApp->property("Style").toString(); label = new QLabel(this); - movie = new QMovie(":/icons/wait.gif"); + movie = new QMovie(iconPath+"/wait.gif"); label->setMovie(movie); label->setAlignment(Qt::AlignCenter); @@ -89,13 +91,11 @@ void WaitingDialog::accept() QFuture future; future = QtConcurrent::run([&]{ - //QTime dieTime = QTime::currentTime().addSecs(1); _dev_inst->set_config(NULL, NULL, SR_CONF_ZERO_SET, g_variant_new_boolean(true)); - //while( QTime::currentTime() < dieTime ); }); Qt::WindowFlags flags = Qt::CustomizeWindowHint; - QProgressDialog dlg(tr("Save Auto Zero Result... It can take a while."), + QProgressDialog dlg(tr("Save calibration Result... It can take a while."), tr("Cancel"),0,0,this,flags); dlg.setWindowModality(Qt::WindowModal); dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | @@ -103,8 +103,8 @@ void WaitingDialog::accept() dlg.setCancelButton(NULL); QFutureWatcher watcher; - watcher.setFuture(future); connect(&watcher,SIGNAL(finished()),&dlg,SLOT(cancel())); + watcher.setFuture(future); dlg.exec(); } @@ -119,14 +119,12 @@ void WaitingDialog::reject() QFuture future; future = QtConcurrent::run([&]{ - //QTime dieTime = QTime::currentTime().addSecs(1); - _dev_inst->set_config(NULL, NULL, SR_CONF_ZERO, g_variant_new_boolean(false)); + _dev_inst->set_config(NULL, NULL, _key, g_variant_new_boolean(false)); _dev_inst->set_config(NULL, NULL, SR_CONF_ZERO_LOAD, g_variant_new_boolean(true)); - //while( QTime::currentTime() < dieTime ); }); Qt::WindowFlags flags = Qt::CustomizeWindowHint; - QProgressDialog dlg(tr("Load Current Setting... It can take a while."), + QProgressDialog dlg(tr("Load current setting... It can take a while."), tr("Cancel"),0,0,this,flags); dlg.setWindowModality(Qt::WindowModal); dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | @@ -164,7 +162,7 @@ void WaitingDialog::changeText() tips->setText(TIPS_WAIT); index = 0; - GVariant* gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_ZERO); + GVariant* gvar = _dev_inst->get_config(NULL, NULL, _key); if (gvar != NULL) { bool zero = g_variant_get_boolean(gvar); g_variant_unref(gvar); diff --git a/DSView/pv/dialogs/waitingdialog.h b/DSView/pv/dialogs/waitingdialog.h old mode 100644 new mode 100755 index 68130835fb5c4e840ddb272441c51b6394ad1b78..5c06e3c93c37ae23c774cce1c66491616a8808d9 --- a/DSView/pv/dialogs/waitingdialog.h +++ b/DSView/pv/dialogs/waitingdialog.h @@ -52,7 +52,7 @@ private: static const QString TIPS_FINISHED; public: - WaitingDialog(QWidget *parent, boost::shared_ptr dev_inst); + WaitingDialog(QWidget *parent, boost::shared_ptr dev_inst, int key); int start(); protected: @@ -64,6 +64,7 @@ private slots: void stop(); private: + int _key; boost::shared_ptr _dev_inst; toolbars::TitleBar *_titlebar; QDialogButtonBox _button_box; diff --git a/DSView/pv/dock/dsotriggerdock.cpp b/DSView/pv/dock/dsotriggerdock.cpp old mode 100644 new mode 100755 index 77f5dcf8f6f10c085c86386d157f1b0aa689ae55..f646f3571de7b497ff32d4eb46759a191185bcff --- a/DSView/pv/dock/dsotriggerdock.cpp +++ b/DSView/pv/dock/dsotriggerdock.cpp @@ -1,420 +1,453 @@ -/* - * This file is part of the DSView project. - * DSView is based on PulseView. - * - * Copyright (C) 2013 DreamSourceLab - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "dsotriggerdock.h" -#include "../sigsession.h" -#include "../device/devinst.h" -#include "../dialogs/dsmessagebox.h" -#include "../view/dsosignal.h" - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -using namespace boost; -using namespace std; - -namespace pv { -namespace dock { - -DsoTriggerDock::DsoTriggerDock(QWidget *parent, SigSession &session) : - QScrollArea(parent), - _session(session) -{ - this->setWidgetResizable(true); - _widget = new QWidget(this); - - QLabel *position_label = new QLabel(tr("Trigger Position: "), _widget); - position_spinBox = new QSpinBox(_widget); - position_spinBox->setRange(0, 99); - position_spinBox->setButtonSymbols(QAbstractSpinBox::NoButtons); - position_slider = new QSlider(Qt::Horizontal, _widget); - position_slider->setRange(0, 99); - connect(position_slider, SIGNAL(valueChanged(int)), position_spinBox, SLOT(setValue(int))); - connect(position_spinBox, SIGNAL(valueChanged(int)), position_slider, SLOT(setValue(int))); - connect(position_slider, SIGNAL(valueChanged(int)), this, SLOT(pos_changed(int))); - - QLabel *holdoff_label = new QLabel(tr("Hold Off Time: "), _widget); - holdoff_comboBox = new QComboBox(_widget); - holdoff_comboBox->addItem(tr("uS"), qVariantFromValue(1000)); - holdoff_comboBox->addItem(tr("mS"), qVariantFromValue(1000000)); - holdoff_comboBox->addItem(tr("S"), qVariantFromValue(1000000000)); - holdoff_comboBox->setCurrentIndex(0); - holdoff_spinBox = new QSpinBox(_widget); - holdoff_spinBox->setRange(0, 999); - holdoff_spinBox->setButtonSymbols(QAbstractSpinBox::NoButtons); - holdoff_slider = new QSlider(Qt::Horizontal, _widget); - holdoff_slider->setRange(0, 999); - connect(holdoff_slider, SIGNAL(valueChanged(int)), holdoff_spinBox, SLOT(setValue(int))); - connect(holdoff_spinBox, SIGNAL(valueChanged(int)), holdoff_slider, SLOT(setValue(int))); - connect(holdoff_slider, SIGNAL(valueChanged(int)), this, SLOT(hold_changed(int))); - connect(holdoff_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(hold_changed(int))); - - QLabel *margin_label = new QLabel(tr("Noise Sensitivity: "), _widget); - margin_slider = new QSlider(Qt::Horizontal, _widget); - margin_slider->setRange(0, 15); - connect(margin_slider, SIGNAL(valueChanged(int)), this, SLOT(margin_changed(int))); - - - QLabel *tSource_labe = new QLabel(tr("Trigger Sources: "), _widget); - QRadioButton *auto_radioButton = new QRadioButton(tr("Auto")); - auto_radioButton->setChecked(true); - QRadioButton *ch0_radioButton = new QRadioButton(tr("Channel 0")); - QRadioButton *ch1_radioButton = new QRadioButton(tr("Channel 1")); - QRadioButton *ch0a1_radioButton = new QRadioButton(tr("Channel 0 && 1")); - QRadioButton *ch0o1_radioButton = new QRadioButton(tr("Channel 0 | 1")); - connect(auto_radioButton, SIGNAL(clicked()), this, SLOT(source_changed())); - connect(ch0_radioButton, SIGNAL(clicked()), this, SLOT(source_changed())); - connect(ch1_radioButton, SIGNAL(clicked()), this, SLOT(source_changed())); - connect(ch0a1_radioButton, SIGNAL(clicked()), this, SLOT(source_changed())); - connect(ch0o1_radioButton, SIGNAL(clicked()), this, SLOT(source_changed())); - - QLabel *tType_labe = new QLabel(tr("Trigger Types: "), _widget); - QRadioButton *rising_radioButton = new QRadioButton(tr("Rising Edge")); - rising_radioButton->setChecked(true); - QRadioButton *falling_radioButton = new QRadioButton(tr("Falling Edge")); - connect(rising_radioButton, SIGNAL(clicked()), this, SLOT(type_changed())); - connect(falling_radioButton, SIGNAL(clicked()), this, SLOT(type_changed())); - - source_group=new QButtonGroup(_widget); - channel_comboBox = new QComboBox(_widget); - type_group=new QButtonGroup(_widget); - - source_group->addButton(auto_radioButton); - source_group->addButton(ch0_radioButton); - source_group->addButton(ch1_radioButton); - source_group->addButton(ch0a1_radioButton); - source_group->addButton(ch0o1_radioButton); - source_group->setId(auto_radioButton, DSO_TRIGGER_AUTO); - source_group->setId(ch0_radioButton, DSO_TRIGGER_CH0); - source_group->setId(ch1_radioButton, DSO_TRIGGER_CH1); - source_group->setId(ch0a1_radioButton, DSO_TRIGGER_CH0A1); - source_group->setId(ch0o1_radioButton, DSO_TRIGGER_CH0O1); - - type_group->addButton(rising_radioButton); - type_group->addButton(falling_radioButton); - type_group->setId(rising_radioButton, DSO_TRIGGER_RISING); - type_group->setId(falling_radioButton, DSO_TRIGGER_FALLING); - - QVBoxLayout *layout = new QVBoxLayout(_widget); - QGridLayout *gLayout = new QGridLayout(); - gLayout->setVerticalSpacing(5); - gLayout->addWidget(position_label, 0, 0); - gLayout->addWidget(position_spinBox, 0, 1); - gLayout->addWidget(new QLabel(tr("%"), _widget), 0, 2); - gLayout->addWidget(position_slider, 1, 0, 1, 4); - - gLayout->addWidget(new QLabel(_widget), 2, 0); - gLayout->addWidget(tSource_labe, 3, 0); - gLayout->addWidget(auto_radioButton, 4, 0); - gLayout->addWidget(channel_comboBox, 4, 1, 1, 3); - gLayout->addWidget(ch0_radioButton, 5, 0); - gLayout->addWidget(ch1_radioButton, 5, 1, 1, 3); - gLayout->addWidget(ch0a1_radioButton, 6, 0); - gLayout->addWidget(ch0o1_radioButton, 6, 1, 1, 3); - - gLayout->addWidget(new QLabel(_widget), 7, 0); - gLayout->addWidget(tType_labe, 8, 0); - gLayout->addWidget(rising_radioButton, 9, 0); - gLayout->addWidget(falling_radioButton, 10, 0); - - gLayout->addWidget(new QLabel(_widget), 11, 0); - gLayout->addWidget(holdoff_label, 12, 0); - gLayout->addWidget(holdoff_spinBox, 12, 1); - gLayout->addWidget(holdoff_comboBox, 12, 2); - gLayout->addWidget(holdoff_slider, 13, 0, 1, 4); - - gLayout->addWidget(new QLabel(_widget), 14, 0); - gLayout->addWidget(margin_label, 15, 0); - gLayout->addWidget(margin_slider, 16, 0, 1, 4); - - gLayout->setColumnStretch(4, 1); - - layout->addLayout(gLayout); - layout->addStretch(1); - _widget->setLayout(layout); - - this->setWidget(_widget); - //_widget->setGeometry(0, 0, sizeHint().width(), 500); - _widget->setObjectName("dsoTriggerWidget"); -} - -DsoTriggerDock::~DsoTriggerDock() -{ -} - -void DsoTriggerDock::paintEvent(QPaintEvent *) -{ -// QStyleOption opt; -// opt.init(this); -// QPainter p(this); -// style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); -} - -void DsoTriggerDock::auto_trig(int index) -{ - source_group->button(DSO_TRIGGER_AUTO)->setChecked(true); - channel_comboBox->setCurrentIndex(index); - source_changed(); - channel_changed(index); -} - -void DsoTriggerDock::pos_changed(int pos) -{ - int ret; - ret = _session.get_device()->set_config(NULL, NULL, - SR_CONF_HORIZ_TRIGGERPOS, - g_variant_new_byte((uint8_t)pos)); - if (!ret) { - dialogs::DSMessageBox msg(this); - msg.mBox()->setText(tr("Trigger Setting Issue")); - msg.mBox()->setInformativeText(tr("Change horiz trigger position failed!")); - msg.mBox()->setStandardButtons(QMessageBox::Ok); - msg.mBox()->setIcon(QMessageBox::Warning); - msg.exec(); - } - set_trig_pos(pos); -} - -void DsoTriggerDock::hold_changed(int hold) -{ - (void)hold; - int ret; - uint64_t holdoff; - if (holdoff_comboBox->currentData().toDouble() == 1000000000) { - holdoff_slider->setRange(0, 10); - } else { - holdoff_slider->setRange(0, 999); - } - holdoff = holdoff_slider->value() * holdoff_comboBox->currentData().toDouble() / 10; - ret = _session.get_device()->set_config(NULL, NULL, - SR_CONF_TRIGGER_HOLDOFF, - g_variant_new_uint64(holdoff)); - - if (!ret) { - dialogs::DSMessageBox msg(this); - msg.mBox()->setText(tr("Trigger Setting Issue")); - msg.mBox()->setInformativeText(tr("Change trigger hold off time failed!")); - msg.mBox()->setStandardButtons(QMessageBox::Ok); - msg.mBox()->setIcon(QMessageBox::Warning); - msg.exec(); - } -} - -void DsoTriggerDock::margin_changed(int margin) -{ - int ret; - ret = _session.get_device()->set_config(NULL, NULL, - SR_CONF_TRIGGER_MARGIN, - g_variant_new_byte(margin)); - if (!ret) { - dialogs::DSMessageBox msg(this); - msg.mBox()->setText(tr("Trigger Setting Issue")); - msg.mBox()->setInformativeText(tr("Change trigger value sensitivity failed!")); - msg.mBox()->setStandardButtons(QMessageBox::Ok); - msg.mBox()->setIcon(QMessageBox::Warning); - msg.exec(); - } -} - -void DsoTriggerDock::source_changed() -{ - int id = source_group->checkedId(); - int ret; - - ret = _session.get_device()->set_config(NULL, NULL, - SR_CONF_TRIGGER_SOURCE, - g_variant_new_byte(id)); - if (!ret) { - dialogs::DSMessageBox msg(this); - msg.mBox()->setText(tr("Trigger Setting Issue")); - msg.mBox()->setInformativeText(tr("Change trigger source failed!")); - msg.mBox()->setStandardButtons(QMessageBox::Ok); - msg.mBox()->setIcon(QMessageBox::Warning); - msg.exec(); - } -} - -void DsoTriggerDock::channel_changed(int ch) -{ - (void)ch; - int ret; - - ret = _session.get_device()->set_config(NULL, NULL, - SR_CONF_TRIGGER_CHANNEL, - g_variant_new_byte(channel_comboBox->currentData().toInt())); - if (!ret) { - dialogs::DSMessageBox msg(this); - msg.mBox()->setText(tr("Trigger Setting Issue")); - msg.mBox()->setInformativeText(tr("Change trigger channel failed!")); - msg.mBox()->setStandardButtons(QMessageBox::Ok); - msg.mBox()->setIcon(QMessageBox::Warning); - msg.exec(); - } -} - -void DsoTriggerDock::type_changed() -{ - int id = type_group->checkedId(); - int ret; - - ret = _session.get_device()->set_config(NULL, NULL, - SR_CONF_TRIGGER_SLOPE, - g_variant_new_byte(id)); - if (!ret) { - dialogs::DSMessageBox msg(this); - msg.mBox()->setText(tr("Trigger Setting Issue")); - msg.mBox()->setInformativeText(tr("Change trigger type failed!")); - msg.mBox()->setStandardButtons(QMessageBox::Ok); - msg.mBox()->setIcon(QMessageBox::Warning); - msg.exec(); - } -} - -void DsoTriggerDock::device_change() -{ - if (_session.get_device()->name() != "DSLogic") { - position_spinBox->setDisabled(true); - position_slider->setDisabled(true); - } else { - position_spinBox->setDisabled(false); - position_slider->setDisabled(false); - } -} - -void DsoTriggerDock::init() -{ - if (_session.get_device()->name().contains("virtual")) { - foreach(QAbstractButton * btn, source_group->buttons()) - btn->setDisabled(true); - foreach(QAbstractButton * btn, type_group->buttons()) - btn->setDisabled(true); - holdoff_slider->setDisabled(true); - holdoff_spinBox->setDisabled(true); - holdoff_comboBox->setDisabled(true); - margin_slider->setDisabled(true); - channel_comboBox->setDisabled(true); - return; - } else { - foreach(QAbstractButton * btn, source_group->buttons()) - btn->setDisabled(false); - foreach(QAbstractButton * btn, type_group->buttons()) - btn->setDisabled(false); - holdoff_slider->setDisabled(false); - holdoff_spinBox->setDisabled(false); - holdoff_comboBox->setDisabled(false); - margin_slider->setDisabled(false); - channel_comboBox->setDisabled(false); - } - - // TRIGGERPOS - GVariant* gvar = _session.get_device()->get_config(NULL, NULL, - SR_CONF_HORIZ_TRIGGERPOS); - if (gvar != NULL) { - uint16_t pos = g_variant_get_byte(gvar); - g_variant_unref(gvar); - position_slider->setValue(pos); - } - - gvar = _session.get_device()->get_config(NULL, NULL, - SR_CONF_TRIGGER_SOURCE); - if (gvar != NULL) { - uint8_t src = g_variant_get_byte(gvar); - g_variant_unref(gvar); - source_group->button(src)->setChecked(true); - } - - // setup channel_comboBox - disconnect(channel_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(channel_changed(int))); - channel_comboBox->clear(); - BOOST_FOREACH(const boost::shared_ptr s, _session.get_signals()) { - boost::shared_ptr dsoSig; - if ((dsoSig = dynamic_pointer_cast(s))) { - channel_comboBox->addItem(dsoSig->get_name(), qVariantFromValue(dsoSig->get_index())); - } - } - gvar = _session.get_device()->get_config(NULL, NULL, - SR_CONF_TRIGGER_CHANNEL); - if (gvar != NULL) { - uint8_t src = g_variant_get_byte(gvar); - g_variant_unref(gvar); - for (int i = 0; i < channel_comboBox->count(); i++) { - if (src == channel_comboBox->itemData(i).toInt()) { - channel_comboBox->setCurrentIndex(i); - break; - } - } - } - connect(channel_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(channel_changed(int))); - - gvar = _session.get_device()->get_config(NULL, NULL, - SR_CONF_TRIGGER_SLOPE); - if (gvar != NULL) { - uint8_t slope = g_variant_get_byte(gvar); - g_variant_unref(gvar); - type_group->button(slope)->setChecked(true); - } - - disconnect(holdoff_slider, SIGNAL(valueChanged(int)), this, SLOT(hold_changed(int))); - disconnect(holdoff_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(hold_changed(int))); - gvar = _session.get_device()->get_config(NULL, NULL, - SR_CONF_TRIGGER_HOLDOFF); - if (gvar != NULL) { - uint64_t holdoff = g_variant_get_uint64(gvar); - g_variant_unref(gvar); - for (int i = holdoff_comboBox->count()-1; i >= 0; i--) { - if (holdoff >= holdoff_comboBox->itemData(i).toDouble()) { - holdoff_comboBox->setCurrentIndex(i); - break; - } - } - if (holdoff_comboBox->currentData().toDouble() == 1000000000) { - holdoff_slider->setRange(0, 10); - } else { - holdoff_slider->setRange(0, 999); - } - holdoff_spinBox->setValue(holdoff * 10.0/holdoff_comboBox->currentData().toDouble()); - } - connect(holdoff_slider, SIGNAL(valueChanged(int)), this, SLOT(hold_changed(int))); - connect(holdoff_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(hold_changed(int))); - - disconnect(margin_slider, SIGNAL(valueChanged(int)), this, SLOT(margin_changed(int))); - gvar = _session.get_device()->get_config(NULL, NULL, - SR_CONF_TRIGGER_MARGIN); - if (gvar != NULL) { - uint8_t margin = g_variant_get_byte(gvar); - g_variant_unref(gvar); - margin_slider->setValue(margin); - } - connect(margin_slider, SIGNAL(valueChanged(int)), this, SLOT(margin_changed(int))); -} - -} // namespace dock -} // namespace pv +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2013 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "dsotriggerdock.h" +#include "../sigsession.h" +#include "../device/devinst.h" +#include "../dialogs/dsmessagebox.h" +#include "../view/dsosignal.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +using namespace boost; +using namespace std; + +namespace pv { +namespace dock { + +DsoTriggerDock::DsoTriggerDock(QWidget *parent, SigSession &session) : + QScrollArea(parent), + _session(session) +{ + this->setWidgetResizable(true); + _widget = new QWidget(this); + + _position_label = new QLabel(_widget); + _position_spinBox = new QSpinBox(_widget); + _position_spinBox->setRange(0, 99); + _position_spinBox->setButtonSymbols(QAbstractSpinBox::NoButtons); + _position_slider = new QSlider(Qt::Horizontal, _widget); + _position_slider->setRange(0, 99); + connect(_position_slider, SIGNAL(valueChanged(int)), _position_spinBox, SLOT(setValue(int))); + connect(_position_spinBox, SIGNAL(valueChanged(int)), _position_slider, SLOT(setValue(int))); + connect(_position_slider, SIGNAL(valueChanged(int)), this, SLOT(pos_changed(int))); + + _holdoff_label = new QLabel(_widget); + _holdoff_comboBox = new QComboBox(_widget); + _holdoff_comboBox->addItem(tr("uS"), qVariantFromValue(1000)); + _holdoff_comboBox->addItem(tr("mS"), qVariantFromValue(1000000)); + _holdoff_comboBox->addItem(tr("S"), qVariantFromValue(1000000000)); + _holdoff_comboBox->setCurrentIndex(0); + _holdoff_spinBox = new QSpinBox(_widget); + _holdoff_spinBox->setRange(0, 999); + _holdoff_spinBox->setButtonSymbols(QAbstractSpinBox::NoButtons); + _holdoff_slider = new QSlider(Qt::Horizontal, _widget); + _holdoff_slider->setRange(0, 999); + connect(_holdoff_slider, SIGNAL(valueChanged(int)), _holdoff_spinBox, SLOT(setValue(int))); + connect(_holdoff_spinBox, SIGNAL(valueChanged(int)), _holdoff_slider, SLOT(setValue(int))); + connect(_holdoff_slider, SIGNAL(valueChanged(int)), this, SLOT(hold_changed(int))); + connect(_holdoff_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(hold_changed(int))); + + _margin_label = new QLabel(_widget); + _margin_slider = new QSlider(Qt::Horizontal, _widget); + _margin_slider->setRange(0, 15); + connect(_margin_slider, SIGNAL(valueChanged(int)), this, SLOT(margin_changed(int))); + + + _tSource_label = new QLabel(_widget); + _auto_radioButton = new QRadioButton(_widget); + _auto_radioButton->setChecked(true); + _ch0_radioButton = new QRadioButton(_widget); + _ch1_radioButton = new QRadioButton(_widget); + _ch0a1_radioButton = new QRadioButton(_widget); + _ch0o1_radioButton = new QRadioButton(_widget); + connect(_auto_radioButton, SIGNAL(clicked()), this, SLOT(source_changed())); + connect(_ch0_radioButton, SIGNAL(clicked()), this, SLOT(source_changed())); + connect(_ch1_radioButton, SIGNAL(clicked()), this, SLOT(source_changed())); + connect(_ch0a1_radioButton, SIGNAL(clicked()), this, SLOT(source_changed())); + connect(_ch0o1_radioButton, SIGNAL(clicked()), this, SLOT(source_changed())); + + _tType_label = new QLabel(_widget); + _rising_radioButton = new QRadioButton(_widget); + _rising_radioButton->setChecked(true); + _falling_radioButton = new QRadioButton(_widget); + connect(_rising_radioButton, SIGNAL(clicked()), this, SLOT(type_changed())); + connect(_falling_radioButton, SIGNAL(clicked()), this, SLOT(type_changed())); + + _source_group=new QButtonGroup(_widget); + _channel_comboBox = new QComboBox(_widget); + _type_group=new QButtonGroup(_widget); + + _source_group->addButton(_auto_radioButton); + _source_group->addButton(_ch0_radioButton); + _source_group->addButton(_ch1_radioButton); + _source_group->addButton(_ch0a1_radioButton); + _source_group->addButton(_ch0o1_radioButton); + _source_group->setId(_auto_radioButton, DSO_TRIGGER_AUTO); + _source_group->setId(_ch0_radioButton, DSO_TRIGGER_CH0); + _source_group->setId(_ch1_radioButton, DSO_TRIGGER_CH1); + _source_group->setId(_ch0a1_radioButton, DSO_TRIGGER_CH0A1); + _source_group->setId(_ch0o1_radioButton, DSO_TRIGGER_CH0O1); + + _type_group->addButton(_rising_radioButton); + _type_group->addButton(_falling_radioButton); + _type_group->setId(_rising_radioButton, DSO_TRIGGER_RISING); + _type_group->setId(_falling_radioButton, DSO_TRIGGER_FALLING); + + QVBoxLayout *layout = new QVBoxLayout(_widget); + QGridLayout *gLayout = new QGridLayout(); + gLayout->setVerticalSpacing(5); + gLayout->addWidget(_position_label, 0, 0); + gLayout->addWidget(_position_spinBox, 0, 1); + gLayout->addWidget(new QLabel(tr("%"), _widget), 0, 2); + gLayout->addWidget(_position_slider, 1, 0, 1, 4); + + gLayout->addWidget(new QLabel(_widget), 2, 0); + gLayout->addWidget(_tSource_label, 3, 0); + gLayout->addWidget(_auto_radioButton, 4, 0); + gLayout->addWidget(_channel_comboBox, 4, 1, 1, 3); + gLayout->addWidget(_ch0_radioButton, 5, 0); + gLayout->addWidget(_ch1_radioButton, 5, 1, 1, 3); + gLayout->addWidget(_ch0a1_radioButton, 6, 0); + gLayout->addWidget(_ch0o1_radioButton, 6, 1, 1, 3); + + gLayout->addWidget(new QLabel(_widget), 7, 0); + gLayout->addWidget(_tType_label, 8, 0); + gLayout->addWidget(_rising_radioButton, 9, 0); + gLayout->addWidget(_falling_radioButton, 10, 0); + + gLayout->addWidget(new QLabel(_widget), 11, 0); + gLayout->addWidget(_holdoff_label, 12, 0); + gLayout->addWidget(_holdoff_spinBox, 12, 1); + gLayout->addWidget(_holdoff_comboBox, 12, 2); + gLayout->addWidget(_holdoff_slider, 13, 0, 1, 4); + + gLayout->addWidget(new QLabel(_widget), 14, 0); + gLayout->addWidget(_margin_label, 15, 0); + gLayout->addWidget(_margin_slider, 16, 0, 1, 4); + + gLayout->setColumnStretch(4, 1); + + layout->addLayout(gLayout); + layout->addStretch(1); + _widget->setLayout(layout); + + this->setWidget(_widget); + //_widget->setGeometry(0, 0, sizeHint().width(), sizeHint().height()); + _widget->setObjectName("dsoTriggerWidget"); + + retranslateUi(); +} + +DsoTriggerDock::~DsoTriggerDock() +{ +} + +void DsoTriggerDock::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + retranslateUi(); + else if (event->type() == QEvent::StyleChange) + reStyle(); + QScrollArea::changeEvent(event); +} + +void DsoTriggerDock::retranslateUi() +{ + _position_label->setText(tr("Trigger Position: ")); + _holdoff_label->setText(tr("Hold Off Time: ")); + _margin_label->setText(tr("Noise Sensitivity: ")); + _tSource_label->setText(tr("Trigger Sources: ")); + _tType_label->setText(tr("Trigger Types: ")); + _rising_radioButton->setText(tr("Rising Edge")); + _falling_radioButton->setText(tr("Falling Edge")); + + _auto_radioButton->setText(tr("Auto")); + _ch0_radioButton->setText(tr("Channel 0")); + _ch1_radioButton->setText(tr("Channel 1")); + _ch0a1_radioButton->setText(tr("Channel 0 && 1")); + _ch0o1_radioButton->setText(tr("Channel 0 | 1")); +} + +void DsoTriggerDock::reStyle() +{ + //QString iconPath = ":/icons/" + qApp->property("Style").toString(); +} + +void DsoTriggerDock::paintEvent(QPaintEvent *) +{ +// QStyleOption opt; +// opt.init(this); +// QPainter p(this); +// style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); +} + +void DsoTriggerDock::auto_trig(int index) +{ + _source_group->button(DSO_TRIGGER_AUTO)->setChecked(true); + _channel_comboBox->setCurrentIndex(index); + source_changed(); + channel_changed(index); +} + +void DsoTriggerDock::pos_changed(int pos) +{ + int ret; + ret = _session.get_device()->set_config(NULL, NULL, + SR_CONF_HORIZ_TRIGGERPOS, + g_variant_new_byte((uint8_t)pos)); + if (!ret) { + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Trigger Setting Issue")); + msg.mBox()->setInformativeText(tr("Change horiz trigger position failed!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); + msg.exec(); + } + set_trig_pos(pos); +} + +void DsoTriggerDock::hold_changed(int hold) +{ + (void)hold; + int ret; + uint64_t holdoff; + if (_holdoff_comboBox->currentData().toDouble() == 1000000000) { + _holdoff_slider->setRange(0, 10); + } else { + _holdoff_slider->setRange(0, 999); + } + holdoff = _holdoff_slider->value() * _holdoff_comboBox->currentData().toDouble() / 10; + ret = _session.get_device()->set_config(NULL, NULL, + SR_CONF_TRIGGER_HOLDOFF, + g_variant_new_uint64(holdoff)); + + if (!ret) { + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Trigger Setting Issue")); + msg.mBox()->setInformativeText(tr("Change trigger hold off time failed!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); + msg.exec(); + } +} + +void DsoTriggerDock::margin_changed(int margin) +{ + int ret; + ret = _session.get_device()->set_config(NULL, NULL, + SR_CONF_TRIGGER_MARGIN, + g_variant_new_byte(margin)); + if (!ret) { + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Trigger Setting Issue")); + msg.mBox()->setInformativeText(tr("Change trigger value sensitivity failed!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); + msg.exec(); + } +} + +void DsoTriggerDock::source_changed() +{ + int id = _source_group->checkedId(); + int ret; + + ret = _session.get_device()->set_config(NULL, NULL, + SR_CONF_TRIGGER_SOURCE, + g_variant_new_byte(id)); + if (!ret) { + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Trigger Setting Issue")); + msg.mBox()->setInformativeText(tr("Change trigger source failed!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); + msg.exec(); + } +} + +void DsoTriggerDock::channel_changed(int ch) +{ + (void)ch; + int ret; + + ret = _session.get_device()->set_config(NULL, NULL, + SR_CONF_TRIGGER_CHANNEL, + g_variant_new_byte(_channel_comboBox->currentData().toInt())); + if (!ret) { + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Trigger Setting Issue")); + msg.mBox()->setInformativeText(tr("Change trigger channel failed!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); + msg.exec(); + } +} + +void DsoTriggerDock::type_changed() +{ + int id = _type_group->checkedId(); + int ret; + + ret = _session.get_device()->set_config(NULL, NULL, + SR_CONF_TRIGGER_SLOPE, + g_variant_new_byte(id)); + if (!ret) { + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Trigger Setting Issue")); + msg.mBox()->setInformativeText(tr("Change trigger type failed!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); + msg.exec(); + } +} + +void DsoTriggerDock::device_change() +{ + if (_session.get_device()->name() != "DSLogic") { + _position_spinBox->setDisabled(true); + _position_slider->setDisabled(true); + } else { + _position_spinBox->setDisabled(false); + _position_slider->setDisabled(false); + } +} + +void DsoTriggerDock::init() +{ + if (_session.get_device()->name().contains("virtual")) { + foreach(QAbstractButton * btn, _source_group->buttons()) + btn->setDisabled(true); + foreach(QAbstractButton * btn, _type_group->buttons()) + btn->setDisabled(true); + _holdoff_slider->setDisabled(true); + _holdoff_spinBox->setDisabled(true); + _holdoff_comboBox->setDisabled(true); + _margin_slider->setDisabled(true); + _channel_comboBox->setDisabled(true); + return; + } else { + foreach(QAbstractButton * btn, _source_group->buttons()) + btn->setDisabled(false); + foreach(QAbstractButton * btn, _type_group->buttons()) + btn->setDisabled(false); + _holdoff_slider->setDisabled(false); + _holdoff_spinBox->setDisabled(false); + _holdoff_comboBox->setDisabled(false); + _margin_slider->setDisabled(false); + _channel_comboBox->setDisabled(false); + } + + // TRIGGERPOS + GVariant* gvar = _session.get_device()->get_config(NULL, NULL, + SR_CONF_HORIZ_TRIGGERPOS); + if (gvar != NULL) { + uint16_t pos = g_variant_get_byte(gvar); + g_variant_unref(gvar); + _position_slider->setValue(pos); + } + + gvar = _session.get_device()->get_config(NULL, NULL, + SR_CONF_TRIGGER_SOURCE); + if (gvar != NULL) { + uint8_t src = g_variant_get_byte(gvar); + g_variant_unref(gvar); + _source_group->button(src)->setChecked(true); + } + + // setup _channel_comboBox + disconnect(_channel_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(channel_changed(int))); + _channel_comboBox->clear(); + BOOST_FOREACH(const boost::shared_ptr s, _session.get_signals()) { + boost::shared_ptr dsoSig; + if ((dsoSig = dynamic_pointer_cast(s))) { + _channel_comboBox->addItem(dsoSig->get_name(), qVariantFromValue(dsoSig->get_index())); + } + } + gvar = _session.get_device()->get_config(NULL, NULL, + SR_CONF_TRIGGER_CHANNEL); + if (gvar != NULL) { + uint8_t src = g_variant_get_byte(gvar); + g_variant_unref(gvar); + for (int i = 0; i < _channel_comboBox->count(); i++) { + if (src == _channel_comboBox->itemData(i).toInt()) { + _channel_comboBox->setCurrentIndex(i); + break; + } + } + } + connect(_channel_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(channel_changed(int))); + + gvar = _session.get_device()->get_config(NULL, NULL, + SR_CONF_TRIGGER_SLOPE); + if (gvar != NULL) { + uint8_t slope = g_variant_get_byte(gvar); + g_variant_unref(gvar); + _type_group->button(slope)->setChecked(true); + } + + disconnect(_holdoff_slider, SIGNAL(valueChanged(int)), this, SLOT(hold_changed(int))); + disconnect(_holdoff_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(hold_changed(int))); + gvar = _session.get_device()->get_config(NULL, NULL, + SR_CONF_TRIGGER_HOLDOFF); + if (gvar != NULL) { + uint64_t holdoff = g_variant_get_uint64(gvar); + g_variant_unref(gvar); + for (int i = _holdoff_comboBox->count()-1; i >= 0; i--) { + if (holdoff >= _holdoff_comboBox->itemData(i).toDouble()) { + _holdoff_comboBox->setCurrentIndex(i); + break; + } + } + if (_holdoff_comboBox->currentData().toDouble() == 1000000000) { + _holdoff_slider->setRange(0, 10); + } else { + _holdoff_slider->setRange(0, 999); + } + _holdoff_spinBox->setValue(holdoff * 10.0/_holdoff_comboBox->currentData().toDouble()); + } + connect(_holdoff_slider, SIGNAL(valueChanged(int)), this, SLOT(hold_changed(int))); + connect(_holdoff_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(hold_changed(int))); + + disconnect(_margin_slider, SIGNAL(valueChanged(int)), this, SLOT(margin_changed(int))); + gvar = _session.get_device()->get_config(NULL, NULL, + SR_CONF_TRIGGER_MARGIN); + if (gvar != NULL) { + uint8_t margin = g_variant_get_byte(gvar); + g_variant_unref(gvar); + _margin_slider->setValue(margin); + } + connect(_margin_slider, SIGNAL(valueChanged(int)), this, SLOT(margin_changed(int))); +} + +} // namespace dock +} // namespace pv diff --git a/DSView/pv/dock/dsotriggerdock.h b/DSView/pv/dock/dsotriggerdock.h old mode 100644 new mode 100755 index ee8401c4ff9a7cdf619f178d71007ba237fd12bb..b0971b72401a9598947dec44ad902492b911d3ac --- a/DSView/pv/dock/dsotriggerdock.h +++ b/DSView/pv/dock/dsotriggerdock.h @@ -1,92 +1,113 @@ -/* - * This file is part of the DSView project. - * DSView is based on PulseView. - * - * Copyright (C) 2013 DreamSourceLab - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef DSVIEW_PV_DSOTRIGGERDOCK_H -#define DSVIEW_PV_DSOTRIGGERDOCK_H - -#include -#include -#include -#include -#include -#include - -#include - -namespace pv { - -class SigSession; - -namespace dock { - -class DsoTriggerDock : public QScrollArea -{ - Q_OBJECT - -public: - DsoTriggerDock(QWidget *parent, SigSession &session); - ~DsoTriggerDock(); - - void paintEvent(QPaintEvent *); - - void device_change(); - - void init(); - -signals: - void set_trig_pos(int percent); - -public slots: - void auto_trig(int index); - -private slots: - void pos_changed(int pos); - void hold_changed(int hold); - void margin_changed(int margin); - void source_changed(); - void type_changed(); - void channel_changed(int ch); - -private: - -private: - SigSession &_session; - - QWidget *_widget; - - QComboBox *holdoff_comboBox; - QSpinBox *holdoff_spinBox; - QSlider *holdoff_slider; - - QSlider *margin_slider; - - QSpinBox *position_spinBox; - QSlider *position_slider; - - QButtonGroup *source_group; - QComboBox *channel_comboBox; - QButtonGroup *type_group; -}; - -} // namespace dock -} // namespace pv - -#endif // DSVIEW_PV_DSOTRIGGERDOCK_H +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2013 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef DSVIEW_PV_DSOTRIGGERDOCK_H +#define DSVIEW_PV_DSOTRIGGERDOCK_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace pv { + +class SigSession; + +namespace dock { + +class DsoTriggerDock : public QScrollArea +{ + Q_OBJECT + +public: + DsoTriggerDock(QWidget *parent, SigSession &session); + ~DsoTriggerDock(); + + void paintEvent(QPaintEvent *); + + void device_change(); + + void init(); + +private: + void changeEvent(QEvent *event); + void retranslateUi(); + void reStyle(); + +signals: + void set_trig_pos(int percent); + +public slots: + void auto_trig(int index); + +private slots: + void pos_changed(int pos); + void hold_changed(int hold); + void margin_changed(int margin); + void source_changed(); + void type_changed(); + void channel_changed(int ch); + +private: + +private: + SigSession &_session; + + QWidget *_widget; + + QComboBox *_holdoff_comboBox; + QSpinBox *_holdoff_spinBox; + QSlider *_holdoff_slider; + + QSlider *_margin_slider; + + QSpinBox *_position_spinBox; + QSlider *_position_slider; + + QButtonGroup *_source_group; + QComboBox *_channel_comboBox; + QButtonGroup *_type_group; + + QLabel *_position_label; + QLabel *_holdoff_label; + QLabel *_margin_label; + QLabel *_tSource_label; + QLabel *_tType_label; + QRadioButton *_rising_radioButton; + QRadioButton *_falling_radioButton; + + QRadioButton *_auto_radioButton; + QRadioButton *_ch0_radioButton; + QRadioButton *_ch1_radioButton; + QRadioButton *_ch0a1_radioButton; + QRadioButton *_ch0o1_radioButton; +}; + +} // namespace dock +} // namespace pv + +#endif // DSVIEW_PV_DSOTRIGGERDOCK_H diff --git a/DSView/pv/dock/measuredock.cpp b/DSView/pv/dock/measuredock.cpp old mode 100644 new mode 100755 index 46c78f28905c7d1552418387df3e4ca3bb4f6bc5..53284d74726acdb20e93bef65e29df702d6f00ec --- a/DSView/pv/dock/measuredock.cpp +++ b/DSView/pv/dock/measuredock.cpp @@ -1,661 +1,691 @@ -/* - * This file is part of the DSView project. - * DSView is based on PulseView. - * - * Copyright (C) 2013 DreamSourceLab - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include "measuredock.h" -#include "../sigsession.h" -#include "../view/cursor.h" -#include "../view/view.h" -#include "../view/viewport.h" -#include "../view/timemarker.h" -#include "../view/ruler.h" -#include "../view/logicsignal.h" -#include "../data/signaldata.h" -#include "../data/snapshot.h" -#include "../devicemanager.h" -#include "../device/device.h" -#include "../device/file.h" -#include "../dialogs/dsdialog.h" -#include "../dialogs/dsmessagebox.h" - -#include -#include -#include -#include - -using namespace boost; - -namespace pv { -namespace dock { - -using namespace pv::view; - -MeasureDock::MeasureDock(QWidget *parent, View &view, SigSession &session) : - QScrollArea(parent), - _session(session), - _view(view), - _icon_add(":/icons/add.png"), - _icon_add_dis(":/icons/add_dis.png"), - _icon_del(":/icons/del.png"), - _icon_del_dis(":/icons/del_dis.png") -{ - - _widget = new QWidget(this); - //_widget->setSizePolicy(); - - _mouse_groupBox = new QGroupBox(tr("Mouse measurement"), _widget); - _fen_checkBox = new QCheckBox(tr("Enable floating measurement"), _widget); - _fen_checkBox->setChecked(true); - _width_label = new QLabel("#####", _widget); - _period_label = new QLabel("#####", _widget); - _freq_label = new QLabel("#####", _widget); - _duty_label = new QLabel("#####", _widget); - - _mouse_layout = new QGridLayout(); - _mouse_layout->setVerticalSpacing(5); - _mouse_layout->addWidget(_fen_checkBox, 0, 0, 1, 6); - _mouse_layout->addWidget(new QLabel(tr("W: "), _widget), 1, 0); - _mouse_layout->addWidget(_width_label, 1, 1); - _mouse_layout->addWidget(new QLabel(tr("P: "), _widget), 1, 4); - _mouse_layout->addWidget(_period_label, 1, 5); - _mouse_layout->addWidget(new QLabel(tr("F: "), _widget), 2, 4); - _mouse_layout->addWidget(_freq_label, 2, 5); - _mouse_layout->addWidget(new QLabel(tr("D: "), _widget), 2, 0); - _mouse_layout->addWidget(_duty_label, 2, 1); - _mouse_layout->addWidget(new QLabel(_widget), 0, 6); - _mouse_layout->addWidget(new QLabel(_widget), 1, 6); - _mouse_layout->addWidget(new QLabel(_widget), 2, 6); - _mouse_layout->setColumnStretch(5, 1); - _mouse_groupBox->setLayout(_mouse_layout); - - /* cursor distance group */ - _dist_groupBox = new QGroupBox(tr("Cursor Distance"), _widget); - _dist_groupBox->setMinimumWidth(300); - _dist_add_btn = new QToolButton(_widget); - _dist_add_btn->setIcon(_icon_add); - connect(_dist_add_btn, SIGNAL(clicked()), this, SLOT(add_dist_measure())); - - _dist_layout = new QGridLayout(_widget); - _dist_layout->setVerticalSpacing(5); - _dist_layout->addWidget(_dist_add_btn, 0, 0); - _dist_layout->addWidget(new QLabel(_widget), 0, 1, 1, 3); - _dist_layout->addWidget(new QLabel(tr("Time/Samples"), _widget), 0, 4); - _dist_layout->addWidget(new QLabel(_widget), 0, 5, 1, 2); - _dist_layout->setColumnStretch(1, 50); - _dist_layout->setColumnStretch(6, 100); - add_dist_measure(); - _dist_groupBox->setLayout(_dist_layout); - - /* cursor edges group */ - _edge_groupBox = new QGroupBox(tr("Edges"), _widget); - _edge_groupBox->setMinimumWidth(300); - _edge_add_btn = new QToolButton(_widget); - _edge_add_btn->setIcon(_icon_add); - connect(_edge_add_btn, SIGNAL(clicked()), this, SLOT(add_edge_measure())); - - _edge_layout = new QGridLayout(_widget); - _edge_layout->setVerticalSpacing(5); - _edge_layout->addWidget(_edge_add_btn, 0, 0); - _edge_layout->addWidget(new QLabel(_widget), 0, 1, 1, 4); - _edge_layout->addWidget(new QLabel(tr("Channel"), _widget), 0, 5); - _edge_layout->addWidget(new QLabel(tr("Rising/Falling/Edges"), _widget), 0, 6); - _edge_layout->setColumnStretch(1, 50); - //_edge_layout->setColumnStretch(6, 100); - //add_edge_measure(); - _edge_groupBox->setLayout(_edge_layout); - - /* cursors group */ - _cursor_groupBox = new QGroupBox(tr("Cursors"), _widget); - _cursor_layout = new QGridLayout(_widget); - _cursor_layout->addWidget(new QLabel(tr("Time/Samples"), _widget), 0, 2); - _cursor_layout->addWidget(new QLabel(_widget), 0, 3); - _cursor_layout->setColumnStretch(3, 1); - - _cursor_groupBox->setLayout(_cursor_layout); - - QVBoxLayout *layout = new QVBoxLayout(_widget); - layout->addWidget(_mouse_groupBox); - layout->addWidget(_dist_groupBox); - layout->addWidget(_edge_groupBox); - layout->addWidget(_cursor_groupBox); - layout->addStretch(1); - _widget->setLayout(layout); - - connect(_fen_checkBox, SIGNAL(stateChanged(int)), &_view, SLOT(set_measure_en(int))); - connect(&_view, SIGNAL(measure_updated()), this, SLOT(measure_updated())); - - this->setWidget(_widget); - _widget->setGeometry(0, 0, sizeHint().width(), 2000); - _widget->setObjectName("measureWidget"); -} - -MeasureDock::~MeasureDock() -{ -} - -void MeasureDock::paintEvent(QPaintEvent *) -{ -// QStyleOption opt; -// opt.init(this); -// QPainter p(this); -// style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); -} - -void MeasureDock::refresh() -{ - -} - -void MeasureDock::reload() -{ - for (QVector ::const_iterator i = _edge_ch_cmb_vec.begin(); - i != _edge_ch_cmb_vec.end(); i++) { - update_probe_selector(*i); - } - reCalc(); -} - -void MeasureDock::cursor_update() -{ - using namespace pv::data; - - if (!_cursor_pushButton_list.empty()) { - for (QVector ::const_iterator i = _cursor_del_btn_vec.begin(); - i != _cursor_del_btn_vec.end(); i++) - delete (*i); - for (QVector::Iterator i = _cursor_pushButton_list.begin(); - i != _cursor_pushButton_list.end(); i++) - delete (*i); - for (QVector::Iterator i = _curpos_label_list.begin(); - i != _curpos_label_list.end(); i++) - delete (*i); - - _cursor_del_btn_vec.clear(); - _cursor_pushButton_list.clear(); - _curpos_label_list.clear(); - } - - update_dist(); - update_edge(); - - int index = 1; - for(std::list::iterator i = _view.get_cursorList().begin(); - i != _view.get_cursorList().end(); i++) { - QString curCursor = QString::number(index); - - QToolButton *del_btn = new QToolButton(_widget); - del_btn->setIcon(QIcon::fromTheme("measure", - QIcon(":/icons/del.png"))); - del_btn->setCheckable(true); - QPushButton *_cursor_pushButton = new QPushButton(curCursor, _widget); - set_cursor_btn_color(_cursor_pushButton); - QString _cur_text = _view.get_cm_time(index - 1) + "/" + QString::number(_view.get_cursor_samples(index - 1)); - QLabel *_curpos_label = new QLabel(_cur_text, _widget); - _cursor_del_btn_vec.push_back(del_btn); - _cursor_pushButton_list.push_back(_cursor_pushButton); - _curpos_label_list.push_back(_curpos_label); - - _cursor_layout->addWidget(del_btn, 1+index, 0); - _cursor_layout->addWidget(_cursor_pushButton, 1 + index, 1); - _cursor_layout->addWidget(_curpos_label, 1 + index, 2); - - connect(del_btn, SIGNAL(clicked()), this, SLOT(del_cursor())); - connect(_cursor_pushButton, SIGNAL(clicked()), this, SLOT(goto_cursor())); - - index++; - } - - update(); -} - -void MeasureDock::measure_updated() -{ - _width_label->setText(_view.get_measure("width")); - _period_label->setText(_view.get_measure("period")); - _freq_label->setText(_view.get_measure("frequency")); - _duty_label->setText(_view.get_measure("duty")); -} - -void MeasureDock::cursor_moving() -{ - //TimeMarker* grabbed_marker = _view.get_ruler()->get_grabbed_cursor(); - if (_view.cursors_shown()) { - int index = 0; - for(std::list::iterator i = _view.get_cursorList().begin(); - i != _view.get_cursorList().end(); i++) { - QString _cur_text = _view.get_cm_time(index) + "/" + QString::number(_view.get_cursor_samples(index)); - _curpos_label_list.at(index)->setText(_cur_text); - //_curvalue_label_list.at(index)->setText(_view.get_cm_value(index)); - index++; - } - } - - update_dist(); -} - -void MeasureDock::reCalc() -{ - cursor_update(); - update_dist(); - update_edge(); -} - -void MeasureDock::goto_cursor() -{ - int index = 0; - - for (QVector::Iterator i = _cursor_pushButton_list.begin(); - i != _cursor_pushButton_list.end(); i++) { - QPushButton *button = qobject_cast(sender()); - if ((*i) == button) { - _view.set_cursor_middle(index); - break; - } - index++; - } -} - -void MeasureDock::add_dist_measure() -{ - if (_dist_row_widget_vec.size() > Max_Measure_Limits) - return; - - QWidget *row_widget = new QWidget(_widget); - row_widget->setContentsMargins(0,0,0,0); - QHBoxLayout *row_layout = new QHBoxLayout(row_widget); - row_layout->setContentsMargins(0,0,0,0); - row_layout->setSpacing(0); - row_widget->setLayout(row_layout); - _dist_row_widget_vec.push_back(row_widget); - - QToolButton *del_btn = new QToolButton(row_widget); - del_btn->setIcon(QIcon::fromTheme("measure", - QIcon(":/icons/del.png"))); - del_btn->setCheckable(true); - QPushButton *s_btn = new QPushButton(tr(" "), row_widget); - s_btn->setObjectName("dist"); - QPushButton *e_btn = new QPushButton(tr(" "), row_widget); - e_btn->setObjectName("dist"); - QLabel *r_label = new QLabel(row_widget); - QLabel *g_label = new QLabel(tr("-"), row_widget); - g_label->setContentsMargins(0,0,0,0); - _dist_del_btn_vec.push_back(del_btn); - _dist_s_btn_vec.push_back(s_btn); - _dist_e_btn_vec.push_back(e_btn); - _dist_r_label_vec.push_back(r_label); - - connect(del_btn, SIGNAL(clicked()), this, SLOT(del_dist_measure())); - connect(s_btn, SIGNAL(clicked()), this, SLOT(show_all_coursor())); - connect(e_btn, SIGNAL(clicked()), this, SLOT(show_all_coursor())); - - row_layout->addWidget(del_btn); - row_layout->addSpacing(5); - row_layout->addWidget(s_btn); - row_layout->addWidget(g_label); - row_layout->addWidget(e_btn); - row_layout->addSpacing(5); - row_layout->addWidget(r_label, 100); - - _dist_layout->addWidget(row_widget, _dist_row_widget_vec.size(), 0, 1, 7); - -} - -void MeasureDock::del_dist_measure() -{ - int del_index = 0; - for (QVector ::const_iterator i = _dist_del_btn_vec.begin(); - i != _dist_del_btn_vec.end(); i++) { - if ((*i)->isChecked()) { - _dist_layout->removeWidget(_dist_row_widget_vec.at(del_index)); - - delete _dist_del_btn_vec.at(del_index); - delete _dist_s_btn_vec.at(del_index); - delete _dist_e_btn_vec.at(del_index); - delete _dist_r_label_vec.at(del_index); - delete _dist_row_widget_vec.at(del_index); - - _dist_del_btn_vec.remove(del_index); - _dist_s_btn_vec.remove(del_index); - _dist_e_btn_vec.remove(del_index); - _dist_r_label_vec.remove(del_index); - _dist_row_widget_vec.remove(del_index); - - break; - } - del_index++; - } -} - -void MeasureDock::add_edge_measure() -{ - if (_edge_row_widget_vec.size() > Max_Measure_Limits) - return; - - QWidget *row_widget = new QWidget(_widget); - row_widget->setContentsMargins(0,0,0,0); - QHBoxLayout *row_layout = new QHBoxLayout(row_widget); - row_layout->setContentsMargins(0,0,0,0); - row_layout->setSpacing(0); - row_widget->setLayout(row_layout); - _edge_row_widget_vec.push_back(row_widget); - - QToolButton *del_btn = new QToolButton(row_widget); - del_btn->setIcon(QIcon::fromTheme("measure", - QIcon(":/icons/del.png"))); - del_btn->setCheckable(true); - QPushButton *s_btn = new QPushButton(tr(" "), row_widget); - s_btn->setObjectName("edge"); - QPushButton *e_btn = new QPushButton(tr(" "), row_widget); - e_btn->setObjectName("edge"); - QLabel *r_label = new QLabel(row_widget); - QLabel *g_label = new QLabel(tr("-"), row_widget); - g_label->setContentsMargins(0,0,0,0); - QLabel *a_label = new QLabel(tr("@"), row_widget); - a_label->setContentsMargins(0,0,0,0); - QComboBox *ch_cmb = create_probe_selector(row_widget); - _edge_del_btn_vec.push_back(del_btn); - _edge_s_btn_vec.push_back(s_btn); - _edge_e_btn_vec.push_back(e_btn); - _edge_ch_cmb_vec.push_back(ch_cmb); - _edge_r_label_vec.push_back(r_label); - - connect(del_btn, SIGNAL(clicked()), this, SLOT(del_edge_measure())); - connect(s_btn, SIGNAL(clicked()), this, SLOT(show_all_coursor())); - connect(e_btn, SIGNAL(clicked()), this, SLOT(show_all_coursor())); - connect(ch_cmb, SIGNAL(currentIndexChanged(int)), this, SLOT(update_edge())); - - row_layout->addWidget(del_btn); - row_layout->addSpacing(5); - row_layout->addWidget(s_btn); - row_layout->addWidget(g_label); - row_layout->addWidget(e_btn); - row_layout->addWidget(a_label); - row_layout->addWidget(ch_cmb); - row_layout->addSpacing(5); - row_layout->addWidget(r_label, 100); - - _edge_layout->addWidget(row_widget, _edge_row_widget_vec.size(), 0, 1, 7); - -} - -void MeasureDock::del_edge_measure() -{ - int del_index = 0; - for (QVector ::const_iterator i = _edge_del_btn_vec.begin(); - i != _edge_del_btn_vec.end(); i++) { - if ((*i)->isChecked()) { - _edge_layout->removeWidget(_edge_row_widget_vec.at(del_index)); - - delete _edge_del_btn_vec.at(del_index); - delete _edge_s_btn_vec.at(del_index); - delete _edge_e_btn_vec.at(del_index); - delete _edge_r_label_vec.at(del_index); - delete _edge_ch_cmb_vec.at(del_index); - delete _edge_row_widget_vec.at(del_index); - - _edge_del_btn_vec.remove(del_index); - _edge_s_btn_vec.remove(del_index); - _edge_e_btn_vec.remove(del_index); - _edge_r_label_vec.remove(del_index); - _edge_ch_cmb_vec.remove(del_index); - _edge_row_widget_vec.remove(del_index); - - break; - } - del_index++; - } -} - -void MeasureDock::show_all_coursor() -{ - if (_view.get_cursorList().empty()) { - dialogs::DSMessageBox msg(this); - msg.mBox()->setText(tr("Information")); - msg.mBox()->setInformativeText(tr("Please insert cursor before using cursor measure.")); - msg.mBox()->addButton(tr("Ok"), QMessageBox::AcceptRole); - msg.mBox()->setIcon(QMessageBox::Information); - msg.exec(); - - return; - } - - _sel_btn = qobject_cast(sender()); - - //dialogs::DSDialog cursor_dlg(_widget); - QDialog cursor_dlg(_widget); - cursor_dlg.setWindowFlags(Qt::FramelessWindowHint | Qt::Popup | Qt::WindowSystemMenuHint | - Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint); - int index = 0; - QHBoxLayout *hlayout = NULL; - QVBoxLayout *vlayout = new QVBoxLayout(&cursor_dlg); - for(std::list::iterator i = _view.get_cursorList().begin(); - i != _view.get_cursorList().end(); i++) { - QPushButton *cursor_btn = new QPushButton(QString::number(index+1), &cursor_dlg); - set_cursor_btn_color(cursor_btn); - if ((index % 4) == 0) { - hlayout = new QHBoxLayout(&cursor_dlg); - vlayout->addLayout(hlayout); - //cursor_dlg.layout()->addLayout(hlayout); - } - hlayout->addWidget(cursor_btn); - connect(cursor_btn, SIGNAL(clicked()), &cursor_dlg, SLOT(accept())); - connect(cursor_btn, SIGNAL(clicked()), this, SLOT(set_se_cursor())); - index++; - } - while((index++ % 4) != 0) - hlayout->addWidget(new QLabel(&cursor_dlg)); - - cursor_dlg.setLayout(vlayout); - QRect sel_btn_rect = _sel_btn->geometry(); - sel_btn_rect.moveTopLeft(_sel_btn->parentWidget()->mapToGlobal(sel_btn_rect.topLeft())); - cursor_dlg.setGeometry(sel_btn_rect.left(), sel_btn_rect.bottom()+10, - cursor_dlg.width(), cursor_dlg.height()); - cursor_dlg.exec(); -} - -void MeasureDock::set_se_cursor() -{ - QPushButton *sc = qobject_cast(sender()); - if (_sel_btn) - _sel_btn->setText(sc->text()); - - set_cursor_btn_color(_sel_btn); - - if (_sel_btn->objectName() == "dist") - update_dist(); - else if (_sel_btn->objectName() == "edge") - update_edge(); -} - -const view::Cursor* MeasureDock::find_cousor(int index) -{ - int cur_index = 1; - for(std::list::iterator i = _view.get_cursorList().begin(); - i != _view.get_cursorList().end(); i++) { - if (cur_index == index) { - return (*i); - } - } - - return NULL; -} - -void MeasureDock::update_dist() -{ - int dist_index = 0; - for (QVector::Iterator i = _dist_s_btn_vec.begin(); - i != _dist_s_btn_vec.end(); i++) { - bool start_ret, end_ret; - const unsigned int start = (*i)->text().toInt(&start_ret) - 1; - const unsigned int end = _dist_e_btn_vec[dist_index]->text().toInt(&end_ret) - 1; - - if (start_ret) { - if (start + 1 > _view.get_cursorList().size()) { - (*i)->setText(" "); - set_cursor_btn_color((*i)); - start_ret = false; - } - } - if (end_ret) { - if (end + 1 > _view.get_cursorList().size()) { - _dist_e_btn_vec[dist_index]->setText(" "); - set_cursor_btn_color(_dist_e_btn_vec[dist_index]); - end_ret = false; - } - } - - if (start_ret && end_ret) { - int64_t delta = _view.get_cursor_samples(start) - - _view.get_cursor_samples(end); - QString delta_text = _view.get_cm_delta(start, end) + - "/" + QString::number(delta); - if (delta < 0) - delta_text.replace('+', '-'); - _dist_r_label_vec[dist_index]->setText(delta_text); - } else { - _dist_r_label_vec[dist_index]->setText(" "); - } - - dist_index++; - } -} - -void MeasureDock::update_edge() -{ - int edge_index = 0; - for (QVector::Iterator i = _edge_s_btn_vec.begin(); - i != _edge_s_btn_vec.end(); i++) { - bool start_ret, end_ret; - const unsigned int start = (*i)->text().toInt(&start_ret) - 1; - const unsigned int end = _edge_e_btn_vec[edge_index]->text().toInt(&end_ret) - 1; - - if (start_ret) { - if (start + 1 > _view.get_cursorList().size()) { - (*i)->setText(" "); - set_cursor_btn_color((*i)); - start_ret = false; - } - } - if (end_ret) { - if (end + 1 > _view.get_cursorList().size()) { - _edge_e_btn_vec[edge_index]->setText(" "); - set_cursor_btn_color(_edge_e_btn_vec[edge_index]); - end_ret = false; - } - } - - bool mValid = false; - if (start_ret && end_ret) { - uint64_t rising_edges; - uint64_t falling_edges; - const std::vector< boost::shared_ptr > sigs(_session.get_signals()); - for(size_t i = 0; i < sigs.size(); i++) { - const boost::shared_ptr s(sigs[i]); - boost::shared_ptr logicSig; - assert(s); - if ((logicSig = dynamic_pointer_cast(s)) && - (logicSig->enabled()) && - (logicSig->get_index() == _edge_ch_cmb_vec[edge_index]->currentText().toInt())){ - if (logicSig->edges(_view.get_cursor_samples(end), _view.get_cursor_samples(start), rising_edges, falling_edges)) { - QString delta_text = QString::number(rising_edges) + "/" + - QString::number(falling_edges) + "/" + - QString::number(rising_edges + falling_edges); - _edge_r_label_vec[edge_index]->setText(delta_text); - mValid = true; - break; - } - } - } - } - - if (!mValid) - _edge_r_label_vec[edge_index]->setText("-/-/-"); - - edge_index++; - } -} - -void MeasureDock::set_cursor_btn_color(QPushButton *btn) -{ - bool ret; - const unsigned int start = btn->text().toInt(&ret) - 1; - QColor cursor_color = ret ? view::Ruler::CursorColor[start%8] : QColor("#302F2F"); - QString border_width = ret ? "0px" : "1px"; - QString normal = "{background-color:" + cursor_color.name() + - "; color:black" + "; border-width:" + border_width + ";}"; - QString hover = "{background-color:" + cursor_color.darker().name() + - "; color:black" + "; border-width:" + border_width + ";}"; - QString style = "QPushButton:hover" + hover + - "QPushButton" + normal; - btn->setStyleSheet(style); -} - -QComboBox* MeasureDock::create_probe_selector(QWidget *parent) -{ - QComboBox *selector = new QComboBox(parent); - update_probe_selector(selector); - return selector; -} - -void MeasureDock::update_probe_selector(QComboBox *selector) -{ - selector->clear(); - const std::vector< boost::shared_ptr > sigs(_session.get_signals()); - for(size_t i = 0; i < sigs.size(); i++) { - const boost::shared_ptr s(sigs[i]); - assert(s); - - if (dynamic_pointer_cast(s) && s->enabled()) - { - selector->addItem(QString::number(s->get_index())); - } - } -} - -void MeasureDock::del_cursor() -{ - int del_index = 0; - Cursor* cursor = NULL; - for (QVector ::const_iterator i = _cursor_del_btn_vec.begin(); - i != _cursor_del_btn_vec.end(); i++) { - if ((*i)->isChecked()) { - int cur_index = 0; - std::list::iterator ite = _view.get_cursorList().begin(); - while (cur_index++ != del_index) - ite++; - cursor = *ite; - break; - } - del_index++; - } - - if (cursor) - _view.del_cursor(cursor); - if (_view.get_cursorList().empty()) - _view.show_cursors(false); - - cursor_update(); - _view.update(); -} - -} // namespace dock -} // namespace pv +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2013 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "measuredock.h" +#include "../sigsession.h" +#include "../view/cursor.h" +#include "../view/view.h" +#include "../view/viewport.h" +#include "../view/timemarker.h" +#include "../view/ruler.h" +#include "../view/logicsignal.h" +#include "../data/signaldata.h" +#include "../data/snapshot.h" +#include "../devicemanager.h" +#include "../device/device.h" +#include "../device/file.h" +#include "../dialogs/dsdialog.h" +#include "../dialogs/dsmessagebox.h" + +#include +#include +#include +#include + +using namespace boost; + +namespace pv { +namespace dock { + +using namespace pv::view; + +MeasureDock::MeasureDock(QWidget *parent, View &view, SigSession &session) : + QScrollArea(parent), + _session(session), + _view(view) +{ + + _widget = new QWidget(this); + //_widget->setSizePolicy(); + + _mouse_groupBox = new QGroupBox(_widget); + _fen_checkBox = new QCheckBox(_widget); + _fen_checkBox->setChecked(true); + _width_label = new QLabel("#####", _widget); + _period_label = new QLabel("#####", _widget); + _freq_label = new QLabel("#####", _widget); + _duty_label = new QLabel("#####", _widget); + + _w_label = new QLabel(_widget); + _p_label = new QLabel(_widget); + _f_label = new QLabel(_widget); + _d_label = new QLabel(_widget); + _mouse_layout = new QGridLayout(); + _mouse_layout->setVerticalSpacing(5); + _mouse_layout->addWidget(_fen_checkBox, 0, 0, 1, 6); + _mouse_layout->addWidget(_w_label, 1, 0); + _mouse_layout->addWidget(_width_label, 1, 1); + _mouse_layout->addWidget(_p_label, 1, 4); + _mouse_layout->addWidget(_period_label, 1, 5); + _mouse_layout->addWidget(_f_label, 2, 4); + _mouse_layout->addWidget(_freq_label, 2, 5); + _mouse_layout->addWidget(_d_label, 2, 0); + _mouse_layout->addWidget(_duty_label, 2, 1); + _mouse_layout->addWidget(new QLabel(_widget), 0, 6); + _mouse_layout->addWidget(new QLabel(_widget), 1, 6); + _mouse_layout->addWidget(new QLabel(_widget), 2, 6); + _mouse_layout->setColumnStretch(5, 1); + _mouse_groupBox->setLayout(_mouse_layout); + + /* cursor distance group */ + _dist_groupBox = new QGroupBox(_widget); + _dist_groupBox->setMinimumWidth(300); + _dist_add_btn = new QToolButton(_widget); + connect(_dist_add_btn, SIGNAL(clicked()), this, SLOT(add_dist_measure())); + + _dist_layout = new QGridLayout(_widget); + _dist_layout->setVerticalSpacing(5); + _dist_layout->addWidget(_dist_add_btn, 0, 0); + _dist_layout->addWidget(new QLabel(_widget), 0, 1, 1, 3); + _dist_layout->addWidget(new QLabel(tr("Time/Samples"), _widget), 0, 4); + _dist_layout->addWidget(new QLabel(_widget), 0, 5, 1, 2); + _dist_layout->setColumnStretch(1, 50); + _dist_layout->setColumnStretch(6, 100); + _dist_groupBox->setLayout(_dist_layout); + + /* cursor edges group */ + _edge_groupBox = new QGroupBox(_widget); + _edge_groupBox->setMinimumWidth(300); + _edge_add_btn = new QToolButton(_widget); + connect(_edge_add_btn, SIGNAL(clicked()), this, SLOT(add_edge_measure())); + + _channel_label = new QLabel(_widget); + _edge_label = new QLabel(_widget); + _edge_layout = new QGridLayout(_widget); + _edge_layout->setVerticalSpacing(5); + _edge_layout->addWidget(_edge_add_btn, 0, 0); + _edge_layout->addWidget(new QLabel(_widget), 0, 1, 1, 4); + _edge_layout->addWidget(_channel_label, 0, 5); + _edge_layout->addWidget(_edge_label, 0, 6); + _edge_layout->setColumnStretch(1, 50); + //_edge_layout->setColumnStretch(6, 100); + //add_edge_measure(); + _edge_groupBox->setLayout(_edge_layout); + + /* cursors group */ + _time_label = new QLabel(_widget); + _cursor_groupBox = new QGroupBox(_widget); + _cursor_layout = new QGridLayout(_widget); + _cursor_layout->addWidget(_time_label, 0, 2); + _cursor_layout->addWidget(new QLabel(_widget), 0, 3); + _cursor_layout->setColumnStretch(3, 1); + + _cursor_groupBox->setLayout(_cursor_layout); + + QVBoxLayout *layout = new QVBoxLayout(_widget); + layout->addWidget(_mouse_groupBox); + layout->addWidget(_dist_groupBox); + layout->addWidget(_edge_groupBox); + layout->addWidget(_cursor_groupBox); + layout->addStretch(1); + _widget->setLayout(layout); + + connect(_fen_checkBox, SIGNAL(stateChanged(int)), &_view, SLOT(set_measure_en(int))); + connect(&_view, SIGNAL(measure_updated()), this, SLOT(measure_updated())); + + this->setWidget(_widget); + _widget->setGeometry(0, 0, sizeHint().width(), 2000); + _widget->setObjectName("measureWidget"); + + retranslateUi(); +} + +MeasureDock::~MeasureDock() +{ +} + +void MeasureDock::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + retranslateUi(); + else if (event->type() == QEvent::StyleChange) + reStyle(); + QScrollArea::changeEvent(event); +} + +void MeasureDock::retranslateUi() +{ + _mouse_groupBox->setTitle(tr("Mouse measurement")); + _fen_checkBox->setText(tr("Enable floating measurement")); + _dist_groupBox->setTitle(tr("Cursor Distance")); + _edge_groupBox->setTitle(tr("Edges")); + _cursor_groupBox->setTitle(tr("Cursors")); + + _channel_label->setText(tr("Channel")); + _edge_label->setText(tr("Rising/Falling/Edges")); + _time_label->setText(tr("Time/Samples")); + + _w_label->setText(tr("W: ")); + _p_label->setText(tr("P: ")); + _f_label->setText(tr("F: ")); + _d_label->setText(tr("D: ")); +} + +void MeasureDock::reStyle() +{ + QString iconPath = ":/icons/" + qApp->property("Style").toString(); + + _dist_add_btn->setIcon(QIcon(iconPath+"/add.png")); + _edge_add_btn->setIcon(QIcon(iconPath+"/add.png")); + + for (QVector ::const_iterator i = _dist_del_btn_vec.begin(); + i != _dist_del_btn_vec.end(); i++) + (*i)->setIcon(QIcon(iconPath+"/del.png")); + for (QVector ::const_iterator i = _edge_del_btn_vec.begin(); + i != _edge_del_btn_vec.end(); i++) + (*i)->setIcon(QIcon(iconPath+"/del.png")); +} + +void MeasureDock::paintEvent(QPaintEvent *) +{ +// QStyleOption opt; +// opt.init(this); +// QPainter p(this); +// style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); +} + +void MeasureDock::refresh() +{ + +} + +void MeasureDock::reload() +{ + if (_session.get_device()->dev_inst()->mode == LOGIC) + _edge_groupBox->setDisabled(false); + else + _edge_groupBox->setDisabled(true); + + for (QVector ::const_iterator i = _edge_ch_cmb_vec.begin(); + i != _edge_ch_cmb_vec.end(); i++) { + update_probe_selector(*i); + } + reCalc(); +} + +void MeasureDock::cursor_update() +{ + using namespace pv::data; + + if (!_cursor_pushButton_list.empty()) { + for (QVector ::const_iterator i = _cursor_del_btn_vec.begin(); + i != _cursor_del_btn_vec.end(); i++) + (*i)->deleteLater(); + for (QVector::Iterator i = _cursor_pushButton_list.begin(); + i != _cursor_pushButton_list.end(); i++) + (*i)->deleteLater(); + for (QVector::Iterator i = _curpos_label_list.begin(); + i != _curpos_label_list.end(); i++) + (*i)->deleteLater(); + + _cursor_del_btn_vec.clear(); + _cursor_pushButton_list.clear(); + _curpos_label_list.clear(); + } + + update_dist(); + update_edge(); + + int index = 1; + QString iconPath = ":/icons/" + qApp->property("Style").toString(); + for(std::list::iterator i = _view.get_cursorList().begin(); + i != _view.get_cursorList().end(); i++) { + QString curCursor = QString::number(index); + + QToolButton *del_btn = new QToolButton(_widget); + del_btn->setIcon(QIcon(iconPath+"/del.png")); + del_btn->setCheckable(true); + QPushButton *_cursor_pushButton = new QPushButton(curCursor, _widget); + set_cursor_btn_color(_cursor_pushButton); + QString _cur_text = _view.get_cm_time(index - 1) + "/" + QString::number(_view.get_cursor_samples(index - 1)); + QLabel *_curpos_label = new QLabel(_cur_text, _widget); + _cursor_del_btn_vec.push_back(del_btn); + _cursor_pushButton_list.push_back(_cursor_pushButton); + _curpos_label_list.push_back(_curpos_label); + + _cursor_layout->addWidget(del_btn, 1+index, 0); + _cursor_layout->addWidget(_cursor_pushButton, 1 + index, 1); + _cursor_layout->addWidget(_curpos_label, 1 + index, 2); + + connect(del_btn, SIGNAL(clicked()), this, SLOT(del_cursor())); + connect(_cursor_pushButton, SIGNAL(clicked()), this, SLOT(goto_cursor())); + + index++; + } + + update(); +} + +void MeasureDock::measure_updated() +{ + _width_label->setText(_view.get_measure("width")); + _period_label->setText(_view.get_measure("period")); + _freq_label->setText(_view.get_measure("frequency")); + _duty_label->setText(_view.get_measure("duty")); +} + +void MeasureDock::cursor_moving() +{ + //TimeMarker* grabbed_marker = _view.get_ruler()->get_grabbed_cursor(); + if (_view.cursors_shown()) { + int index = 0; + for(std::list::iterator i = _view.get_cursorList().begin(); + i != _view.get_cursorList().end(); i++) { + QString _cur_text = _view.get_cm_time(index) + "/" + QString::number(_view.get_cursor_samples(index)); + _curpos_label_list.at(index)->setText(_cur_text); + //_curvalue_label_list.at(index)->setText(_view.get_cm_value(index)); + index++; + } + } + + update_dist(); +} + +void MeasureDock::reCalc() +{ + cursor_update(); + update_dist(); + update_edge(); +} + +void MeasureDock::goto_cursor() +{ + int index = 0; + + for (QVector::Iterator i = _cursor_pushButton_list.begin(); + i != _cursor_pushButton_list.end(); i++) { + QPushButton *button = qobject_cast(sender()); + if ((*i) == button) { + _view.set_cursor_middle(index); + break; + } + index++; + } +} + +void MeasureDock::add_dist_measure() +{ + if (_dist_row_widget_vec.size() > Max_Measure_Limits) + return; + + QWidget *row_widget = new QWidget(_widget); + row_widget->setContentsMargins(0,0,0,0); + QHBoxLayout *row_layout = new QHBoxLayout(row_widget); + row_layout->setContentsMargins(0,0,0,0); + row_layout->setSpacing(0); + row_widget->setLayout(row_layout); + _dist_row_widget_vec.push_back(row_widget); + + QString iconPath = ":/icons/" + qApp->property("Style").toString(); + QToolButton *del_btn = new QToolButton(row_widget); + del_btn->setIcon(QIcon(iconPath+"/del.png")); + del_btn->setCheckable(true); + QPushButton *s_btn = new QPushButton(tr(" "), row_widget); + s_btn->setObjectName("dist"); + QPushButton *e_btn = new QPushButton(tr(" "), row_widget); + e_btn->setObjectName("dist"); + QLabel *r_label = new QLabel(row_widget); + QLabel *g_label = new QLabel(tr("-"), row_widget); + g_label->setContentsMargins(0,0,0,0); + _dist_del_btn_vec.push_back(del_btn); + _dist_s_btn_vec.push_back(s_btn); + _dist_e_btn_vec.push_back(e_btn); + _dist_r_label_vec.push_back(r_label); + + connect(del_btn, SIGNAL(clicked()), this, SLOT(del_dist_measure())); + connect(s_btn, SIGNAL(clicked()), this, SLOT(show_all_coursor())); + connect(e_btn, SIGNAL(clicked()), this, SLOT(show_all_coursor())); + + row_layout->addWidget(del_btn); + row_layout->addSpacing(5); + row_layout->addWidget(s_btn); + row_layout->addWidget(g_label); + row_layout->addWidget(e_btn); + row_layout->addSpacing(5); + row_layout->addWidget(r_label, 100); + + _dist_layout->addWidget(row_widget, _dist_row_widget_vec.size(), 0, 1, 7); + +} + +void MeasureDock::del_dist_measure() +{ + int del_index = 0; + for (QVector ::const_iterator i = _dist_del_btn_vec.begin(); + i != _dist_del_btn_vec.end(); i++) { + if ((*i)->isChecked()) { + _dist_layout->removeWidget(_dist_row_widget_vec.at(del_index)); + _dist_row_widget_vec.at(del_index)->deleteLater(); + + _dist_del_btn_vec.remove(del_index); + _dist_s_btn_vec.remove(del_index); + _dist_e_btn_vec.remove(del_index); + _dist_r_label_vec.remove(del_index); + _dist_row_widget_vec.remove(del_index); + + break; + } + del_index++; + } +} + +void MeasureDock::add_edge_measure() +{ + if (_edge_row_widget_vec.size() > Max_Measure_Limits) + return; + + QWidget *row_widget = new QWidget(_widget); + row_widget->setContentsMargins(0,0,0,0); + QHBoxLayout *row_layout = new QHBoxLayout(row_widget); + row_layout->setContentsMargins(0,0,0,0); + row_layout->setSpacing(0); + row_widget->setLayout(row_layout); + _edge_row_widget_vec.push_back(row_widget); + + QString iconPath = ":/icons/" + qApp->property("Style").toString(); + QToolButton *del_btn = new QToolButton(row_widget); + del_btn->setIcon(QIcon(iconPath+"/del.png")); + del_btn->setCheckable(true); + QPushButton *s_btn = new QPushButton(tr(" "), row_widget); + s_btn->setObjectName("edge"); + QPushButton *e_btn = new QPushButton(tr(" "), row_widget); + e_btn->setObjectName("edge"); + QLabel *r_label = new QLabel(row_widget); + QLabel *g_label = new QLabel(tr("-"), row_widget); + g_label->setContentsMargins(0,0,0,0); + QLabel *a_label = new QLabel(tr("@"), row_widget); + a_label->setContentsMargins(0,0,0,0); + QComboBox *ch_cmb = create_probe_selector(row_widget); + _edge_del_btn_vec.push_back(del_btn); + _edge_s_btn_vec.push_back(s_btn); + _edge_e_btn_vec.push_back(e_btn); + _edge_ch_cmb_vec.push_back(ch_cmb); + _edge_r_label_vec.push_back(r_label); + + connect(del_btn, SIGNAL(clicked()), this, SLOT(del_edge_measure())); + connect(s_btn, SIGNAL(clicked()), this, SLOT(show_all_coursor())); + connect(e_btn, SIGNAL(clicked()), this, SLOT(show_all_coursor())); + connect(ch_cmb, SIGNAL(currentIndexChanged(int)), this, SLOT(update_edge())); + + row_layout->addWidget(del_btn); + row_layout->addSpacing(5); + row_layout->addWidget(s_btn); + row_layout->addWidget(g_label); + row_layout->addWidget(e_btn); + row_layout->addWidget(a_label); + row_layout->addWidget(ch_cmb); + row_layout->addSpacing(5); + row_layout->addWidget(r_label, 100); + + _edge_layout->addWidget(row_widget, _edge_row_widget_vec.size(), 0, 1, 7); + +} + +void MeasureDock::del_edge_measure() +{ + int del_index = 0; + for (QVector ::const_iterator i = _edge_del_btn_vec.begin(); + i != _edge_del_btn_vec.end(); i++) { + if ((*i)->isChecked()) { + _edge_layout->removeWidget(_edge_row_widget_vec.at(del_index)); + _edge_row_widget_vec.at(del_index)->deleteLater(); + + _edge_del_btn_vec.remove(del_index); + _edge_s_btn_vec.remove(del_index); + _edge_e_btn_vec.remove(del_index); + _edge_r_label_vec.remove(del_index); + _edge_ch_cmb_vec.remove(del_index); + _edge_row_widget_vec.remove(del_index); + + break; + } + del_index++; + } +} + +void MeasureDock::show_all_coursor() +{ + if (_view.get_cursorList().empty()) { + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Information")); + msg.mBox()->setInformativeText(tr("Please insert cursor before using cursor measure.")); + msg.mBox()->addButton(tr("Ok"), QMessageBox::AcceptRole); + msg.mBox()->setIcon(QMessageBox::Information); + msg.exec(); + + return; + } + + _sel_btn = qobject_cast(sender()); + + QDialog cursor_dlg(_widget); + cursor_dlg.setWindowFlags(Qt::FramelessWindowHint | Qt::Popup | Qt::WindowSystemMenuHint | + Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint); + + int index = 0; + QGridLayout *glayout = new QGridLayout(&cursor_dlg); + for(std::list::iterator i = _view.get_cursorList().begin(); + i != _view.get_cursorList().end(); i++) { + QPushButton *cursor_btn = new QPushButton(QString::number(index+1), &cursor_dlg); + set_cursor_btn_color(cursor_btn); + glayout->addWidget(cursor_btn, index/4, index%4, 1, 1); + + connect(cursor_btn, SIGNAL(clicked()), &cursor_dlg, SLOT(accept())); + connect(cursor_btn, SIGNAL(clicked()), this, SLOT(set_se_cursor())); + index++; + } + + QRect sel_btn_rect = _sel_btn->geometry(); + sel_btn_rect.moveTopLeft(_sel_btn->parentWidget()->mapToGlobal(sel_btn_rect.topLeft())); + cursor_dlg.setGeometry(sel_btn_rect.left(), sel_btn_rect.bottom()+10, + cursor_dlg.width(), cursor_dlg.height()); + cursor_dlg.exec(); +} + +void MeasureDock::set_se_cursor() +{ + QPushButton *sc = qobject_cast(sender()); + if (_sel_btn) + _sel_btn->setText(sc->text()); + + set_cursor_btn_color(_sel_btn); + + if (_sel_btn->objectName() == "dist") + update_dist(); + else if (_sel_btn->objectName() == "edge") + update_edge(); +} + +const view::Cursor* MeasureDock::find_cousor(int index) +{ + int cur_index = 1; + for(std::list::iterator i = _view.get_cursorList().begin(); + i != _view.get_cursorList().end(); i++) { + if (cur_index == index) { + return (*i); + } + } + + return NULL; +} + +void MeasureDock::update_dist() +{ + int dist_index = 0; + for (QVector::Iterator i = _dist_s_btn_vec.begin(); + i != _dist_s_btn_vec.end(); i++) { + bool start_ret, end_ret; + const unsigned int start = (*i)->text().toInt(&start_ret) - 1; + const unsigned int end = _dist_e_btn_vec[dist_index]->text().toInt(&end_ret) - 1; + + if (start_ret) { + if (start + 1 > _view.get_cursorList().size()) { + (*i)->setText(" "); + set_cursor_btn_color((*i)); + start_ret = false; + } + } + if (end_ret) { + if (end + 1 > _view.get_cursorList().size()) { + _dist_e_btn_vec[dist_index]->setText(" "); + set_cursor_btn_color(_dist_e_btn_vec[dist_index]); + end_ret = false; + } + } + + if (start_ret && end_ret) { + int64_t delta = _view.get_cursor_samples(start) - + _view.get_cursor_samples(end); + QString delta_text = _view.get_cm_delta(start, end) + + "/" + QString::number(delta); + if (delta < 0) + delta_text.replace('+', '-'); + _dist_r_label_vec[dist_index]->setText(delta_text); + } else { + _dist_r_label_vec[dist_index]->setText(" "); + } + + dist_index++; + } +} + +void MeasureDock::update_edge() +{ + int edge_index = 0; + for (QVector::Iterator i = _edge_s_btn_vec.begin(); + i != _edge_s_btn_vec.end(); i++) { + bool start_ret, end_ret; + const unsigned int start = (*i)->text().toInt(&start_ret) - 1; + const unsigned int end = _edge_e_btn_vec[edge_index]->text().toInt(&end_ret) - 1; + + if (start_ret) { + if (start + 1 > _view.get_cursorList().size()) { + (*i)->setText(" "); + set_cursor_btn_color((*i)); + start_ret = false; + } + } + if (end_ret) { + if (end + 1 > _view.get_cursorList().size()) { + _edge_e_btn_vec[edge_index]->setText(" "); + set_cursor_btn_color(_edge_e_btn_vec[edge_index]); + end_ret = false; + } + } + + bool mValid = false; + if (start_ret && end_ret) { + uint64_t rising_edges; + uint64_t falling_edges; + const std::vector< boost::shared_ptr > sigs(_session.get_signals()); + for(size_t i = 0; i < sigs.size(); i++) { + const boost::shared_ptr s(sigs[i]); + boost::shared_ptr logicSig; + assert(s); + if ((logicSig = dynamic_pointer_cast(s)) && + (logicSig->enabled()) && + (logicSig->get_index() == _edge_ch_cmb_vec[edge_index]->currentText().toInt())){ + if (logicSig->edges(_view.get_cursor_samples(end), _view.get_cursor_samples(start), rising_edges, falling_edges)) { + QString delta_text = QString::number(rising_edges) + "/" + + QString::number(falling_edges) + "/" + + QString::number(rising_edges + falling_edges); + _edge_r_label_vec[edge_index]->setText(delta_text); + mValid = true; + break; + } + } + } + } + + if (!mValid) + _edge_r_label_vec[edge_index]->setText("-/-/-"); + + edge_index++; + } +} + +void MeasureDock::set_cursor_btn_color(QPushButton *btn) +{ + bool ret; + const unsigned int start = btn->text().toInt(&ret) - 1; + QColor cursor_color = ret ? view::Ruler::CursorColor[start%8] : QColor("#302F2F"); + QString border_width = ret ? "0px" : "1px"; + QString normal = "{background-color:" + cursor_color.name() + + "; color:black" + "; border-width:" + border_width + ";}"; + QString hover = "{background-color:" + cursor_color.darker().name() + + "; color:black" + "; border-width:" + border_width + ";}"; + QString style = "QPushButton:hover" + hover + + "QPushButton" + normal; + btn->setStyleSheet(style); +} + +QComboBox* MeasureDock::create_probe_selector(QWidget *parent) +{ + QComboBox *selector = new QComboBox(parent); + update_probe_selector(selector); + return selector; +} + +void MeasureDock::update_probe_selector(QComboBox *selector) +{ + selector->clear(); + const std::vector< boost::shared_ptr > sigs(_session.get_signals()); + for(size_t i = 0; i < sigs.size(); i++) { + const boost::shared_ptr s(sigs[i]); + assert(s); + + if (dynamic_pointer_cast(s) && s->enabled()) + { + selector->addItem(QString::number(s->get_index())); + } + } +} + +void MeasureDock::del_cursor() +{ + int del_index = 0; + Cursor* cursor = NULL; + for (QVector ::const_iterator i = _cursor_del_btn_vec.begin(); + i != _cursor_del_btn_vec.end(); i++) { + if ((*i)->isChecked()) { + int cur_index = 0; + std::list::iterator ite = _view.get_cursorList().begin(); + while (cur_index++ != del_index) + ite++; + cursor = *ite; + break; + } + del_index++; + } + + if (cursor) + _view.del_cursor(cursor); + if (_view.get_cursorList().empty()) + _view.show_cursors(false); + + cursor_update(); + _view.update(); +} + +} // namespace dock +} // namespace pv diff --git a/DSView/pv/dock/measuredock.h b/DSView/pv/dock/measuredock.h old mode 100644 new mode 100755 index 920033c8df6b8625ddd346d758a3c3d97b3780ff..c9f9beebcee04d515d3e484532244131f00e7560 --- a/DSView/pv/dock/measuredock.h +++ b/DSView/pv/dock/measuredock.h @@ -1,146 +1,155 @@ -/* - * This file is part of the DSView project. - * DSView is based on PulseView. - * - * Copyright (C) 2013 DreamSourceLab - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef DSVIEW_PV_MEASUREDOCK_H -#define DSVIEW_PV_MEASUREDOCK_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -namespace pv { - -class SigSession; - -namespace view { - class Cursor; - class View; -} - -namespace dock { - -class MeasureDock : public QScrollArea -{ - Q_OBJECT - -private: - static const int Max_Measure_Limits = 16; - -public: - MeasureDock(QWidget *parent, pv::view::View &view, SigSession &session); - ~MeasureDock(); - - void paintEvent(QPaintEvent *); - void reload(); -private: - QComboBox* create_probe_selector(QWidget *parent); - void update_probe_selector(QComboBox *selector); - -signals: - -private slots: - void goto_cursor(); - - void add_dist_measure(); - void del_dist_measure(); - void add_edge_measure(); - void del_edge_measure(); - void show_all_coursor(); - void set_se_cursor(); - const view::Cursor* find_cousor(int index); - void update_dist(); - void update_edge(); - void set_cursor_btn_color(QPushButton *btn); - void del_cursor(); - -public slots: - void cursor_update(); - void cursor_moving(); - void reCalc(); - void measure_updated(); - void refresh(); - -private: - SigSession &_session; - view::View &_view; - - QWidget *_widget; - QGridLayout *_mouse_layout; - QGroupBox *_mouse_groupBox; - QCheckBox *_fen_checkBox; - QLabel *_width_label; - QLabel *_period_label; - QLabel *_freq_label; - QLabel *_duty_label; - - QGridLayout *_dist_layout; - QGroupBox *_dist_groupBox; - QToolButton *_dist_add_btn; - QVector _dist_row_widget_vec; - QVector _dist_del_btn_vec; - QVector _dist_s_btn_vec; - QVector _dist_e_btn_vec; - QVector _dist_r_label_vec; - - QGridLayout *_edge_layout; - QGroupBox *_edge_groupBox; - QToolButton *_edge_add_btn; - QVector _edge_row_widget_vec; - QVector _edge_del_btn_vec; - QVector _edge_s_btn_vec; - QVector _edge_e_btn_vec; - QVector _edge_ch_cmb_vec; - QVector _edge_r_label_vec; - - QPushButton *_sel_btn; - - QGridLayout *_cursor_layout; - QGroupBox *_cursor_groupBox; - QVector _cursor_del_btn_vec; - QVector _cursor_pushButton_list; - QVector _curpos_label_list; - - QIcon _icon_add; - QIcon _icon_add_dis; - QIcon _icon_del; - QIcon _icon_del_dis; -}; - -} // namespace dock -} // namespace pv - -#endif // DSVIEW_PV_MEASUREDOCK_H +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2013 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef DSVIEW_PV_MEASUREDOCK_H +#define DSVIEW_PV_MEASUREDOCK_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +namespace pv { + +class SigSession; + +namespace view { + class Cursor; + class View; +} + +namespace dock { + +class MeasureDock : public QScrollArea +{ + Q_OBJECT + +private: + static const int Max_Measure_Limits = 16; + +public: + MeasureDock(QWidget *parent, pv::view::View &view, SigSession &session); + ~MeasureDock(); + + void paintEvent(QPaintEvent *); + void reload(); + +private: + void changeEvent(QEvent *event); + void retranslateUi(); + void reStyle(); + +private: + QComboBox* create_probe_selector(QWidget *parent); + void update_probe_selector(QComboBox *selector); + +signals: + +private slots: + void goto_cursor(); + + void del_dist_measure(); + void add_edge_measure(); + void del_edge_measure(); + void show_all_coursor(); + void set_se_cursor(); + const view::Cursor* find_cousor(int index); + void update_dist(); + void update_edge(); + void set_cursor_btn_color(QPushButton *btn); + void del_cursor(); + +public slots: + void add_dist_measure(); + void cursor_update(); + void cursor_moving(); + void reCalc(); + void measure_updated(); + void refresh(); + +private: + SigSession &_session; + view::View &_view; + + QWidget *_widget; + QGridLayout *_mouse_layout; + QGroupBox *_mouse_groupBox; + QCheckBox *_fen_checkBox; + QLabel *_width_label; + QLabel *_period_label; + QLabel *_freq_label; + QLabel *_duty_label; + + QGridLayout *_dist_layout; + QGroupBox *_dist_groupBox; + QToolButton *_dist_add_btn; + QVector _dist_row_widget_vec; + QVector _dist_del_btn_vec; + QVector _dist_s_btn_vec; + QVector _dist_e_btn_vec; + QVector _dist_r_label_vec; + + QGridLayout *_edge_layout; + QGroupBox *_edge_groupBox; + QToolButton *_edge_add_btn; + QVector _edge_row_widget_vec; + QVector _edge_del_btn_vec; + QVector _edge_s_btn_vec; + QVector _edge_e_btn_vec; + QVector _edge_ch_cmb_vec; + QVector _edge_r_label_vec; + + QPushButton *_sel_btn; + + QGridLayout *_cursor_layout; + QGroupBox *_cursor_groupBox; + QVector _cursor_del_btn_vec; + QVector _cursor_pushButton_list; + QVector _curpos_label_list; + + QLabel *_channel_label; + QLabel *_edge_label; + QLabel *_time_label; + QLabel *_w_label; + QLabel *_p_label; + QLabel *_f_label; + QLabel *_d_label; +}; + +} // namespace dock +} // namespace pv + +#endif // DSVIEW_PV_MEASUREDOCK_H diff --git a/DSView/pv/dock/protocoldock.cpp b/DSView/pv/dock/protocoldock.cpp old mode 100644 new mode 100755 index e0b8a50bb18f0cf8ac3db0c546636363feb6e119..93ed2add26172422e1c6eb1679c13f6435f9317f --- a/DSView/pv/dock/protocoldock.cpp +++ b/DSView/pv/dock/protocoldock.cpp @@ -1,817 +1,841 @@ -/* - * This file is part of the DSView project. - * DSView is based on PulseView. - * - * Copyright (C) 2013 DreamSourceLab - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "protocoldock.h" -#include "../sigsession.h" -#include "../view/decodetrace.h" -#include "../device/devinst.h" -#include "../data/decodermodel.h" -#include "../data/decoderstack.h" -#include "../dialogs/protocollist.h" -#include "../dialogs/protocolexp.h" -#include "../dialogs/dsmessagebox.h" -#include "../view/view.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace pv { -namespace dock { - -ProtocolDock::ProtocolDock(QWidget *parent, view::View &view, SigSession &session) : - QScrollArea(parent), - _session(session), - _view(view), - _cur_search_index(-1), - _search_edited(false), - _searching(false), - _add_silent(false) -{ - _up_widget = new QWidget(this); - - QHBoxLayout *hori_layout = new QHBoxLayout(); - - _add_button = new QPushButton(_up_widget); - _add_button->setFlat(true); - _add_button->setIcon(QIcon::fromTheme("protocol", - QIcon(":/icons/add.png"))); - _del_all_button = new QPushButton(_up_widget); - _del_all_button->setFlat(true); - _del_all_button->setIcon(QIcon::fromTheme("protocol", - QIcon(":/icons/del.png"))); - _del_all_button->setCheckable(true); - _protocol_combobox = new QComboBox(_up_widget); - - GSList *l = g_slist_sort(g_slist_copy( - (GSList*)srd_decoder_list()), decoder_name_cmp); - for(; l; l = l->next) - { - const srd_decoder *const d = (srd_decoder*)l->data; - assert(d); - - const bool have_probes = (d->channels || d->opt_channels) != 0; - if (true == have_probes) { - _protocol_combobox->addItem(QString::fromUtf8(d->name), qVariantFromValue(l->data)); - } - } - g_slist_free(l); - - hori_layout->addWidget(_add_button); - hori_layout->addWidget(_del_all_button); - hori_layout->addWidget(_protocol_combobox); - hori_layout->addStretch(1); - - connect(_add_button, SIGNAL(clicked()), - this, SLOT(add_protocol())); - connect(_del_all_button, SIGNAL(clicked()), - this, SLOT(del_protocol())); - - _up_layout = new QVBoxLayout(); - _up_layout->addLayout(hori_layout); - _up_layout->addStretch(1); - - _up_widget->setLayout(_up_layout); - _up_widget->setMinimumHeight(150); - -// this->setWidget(_widget); -// _widget->setGeometry(0, 0, sizeHint().width(), 500); -// _widget->setObjectName("protocolWidget"); - - _dn_widget = new QWidget(this); - - _dn_set_button = new QPushButton(_dn_widget); - _dn_set_button->setFlat(true); - _dn_set_button->setIcon(QIcon::fromTheme("protocol", - QIcon(":/icons/gear.png"))); - connect(_dn_set_button, SIGNAL(clicked()), - this, SLOT(set_model())); - - _dn_save_button = new QPushButton(_dn_widget); - _dn_save_button->setFlat(true); - _dn_save_button->setIcon(QIcon::fromTheme("protocol", - QIcon(":/icons/save.png"))); - connect(_dn_save_button, SIGNAL(clicked()), - this, SLOT(export_table_view())); - - _dn_nav_button = new QPushButton(_dn_widget); - _dn_nav_button->setFlat(true); - _dn_nav_button->setIcon(QIcon::fromTheme("protocol", - QIcon(":/icons/nav.png"))); - connect(_dn_nav_button, SIGNAL(clicked()), - this, SLOT(nav_table_view())); - - QHBoxLayout *dn_title_layout = new QHBoxLayout(); - dn_title_layout->addWidget(_dn_set_button, 0, Qt::AlignLeft); - dn_title_layout->addWidget(_dn_save_button, 0, Qt::AlignLeft); - dn_title_layout->addWidget(new QLabel(tr("Protocol List Viewer"), _dn_widget), 1, Qt::AlignLeft); - dn_title_layout->addWidget(_dn_nav_button, 0, Qt::AlignRight); - //dn_title_layout->addStretch(1); - - _table_view = new QTableView(_dn_widget); - _table_view->setModel(_session.get_decoder_model()); - _table_view->setAlternatingRowColors(true); - _table_view->setShowGrid(false); - _table_view->horizontalHeader()->setStretchLastSection(true); - _table_view->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); - _table_view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); - - _pre_button = new QPushButton(_dn_widget); - _nxt_button = new QPushButton(_dn_widget); - _pre_button->setIcon(QIcon::fromTheme("protocol", - QIcon(":/icons/pre.png"))); - _nxt_button->setIcon(QIcon::fromTheme("protocol", - QIcon(":/icons/next.png"))); - connect(_pre_button, SIGNAL(clicked()), - this, SLOT(search_pre())); - connect(_nxt_button, SIGNAL(clicked()), - this, SLOT(search_nxt())); - - QPushButton *search_button = new QPushButton(this); - search_button->setIcon(QIcon::fromTheme("protocol", - QIcon(":/icons/search.png"))); - search_button->setFixedWidth(search_button->height()); - search_button->setDisabled(true); - _search_edit = new QLineEdit(_dn_widget); - _search_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - _search_edit->setPlaceholderText(tr("search")); - QHBoxLayout *search_layout = new QHBoxLayout(); - search_layout->addWidget(search_button); - search_layout->addStretch(1); - search_layout->setContentsMargins(0, 0, 0, 0); - _search_edit->setLayout(search_layout); - _search_edit->setTextMargins(search_button->width(), 0, 0, 0); - - _dn_search_layout = new QHBoxLayout(); - _dn_search_layout->addWidget(_pre_button, 0, Qt::AlignLeft); - _dn_search_layout->addWidget(_search_edit, 1, Qt::AlignLeft); - _dn_search_layout->addWidget(_nxt_button, 0, Qt::AlignRight); - - _matchs_label = new QLabel(_dn_widget); - QHBoxLayout *dn_match_layout = new QHBoxLayout(); - dn_match_layout->addWidget(new QLabel(tr("Matching Items:")), 0, Qt::AlignLeft); - dn_match_layout->addWidget(_matchs_label, 0, Qt::AlignLeft); - dn_match_layout->addStretch(1); - - _dn_layout = new QVBoxLayout(); - _dn_layout->addLayout(dn_title_layout); - _dn_layout->addLayout(_dn_search_layout); - _dn_layout->addLayout(dn_match_layout); - _dn_layout->addWidget(_table_view); - - _dn_widget->setLayout(_dn_layout); - _dn_widget->setMinimumHeight(350); - - _split_widget = new QSplitter(this); - _split_widget->insertWidget(0, _up_widget); - _split_widget->insertWidget(1, _dn_widget); - _split_widget->setOrientation(Qt::Vertical); - _split_widget->setCollapsible(0, false); - _split_widget->setCollapsible(1, false); - //_split_widget->setStretchFactor(1, 1); - //_split_widget - - this->setWidgetResizable(true); - this->setWidget(_split_widget); - //_split_widget->setGeometry(0, 0, sizeHint().width(), 500); - _split_widget->setObjectName("protocolWidget"); - - connect(&_session, SIGNAL(decode_done()), this, SLOT(update_model())); - connect(this, SIGNAL(protocol_updated()), this, SLOT(update_model())); - connect(_table_view, SIGNAL(clicked(QModelIndex)), this, SLOT(item_clicked(QModelIndex))); - connect(_table_view->horizontalHeader(), SIGNAL(sectionResized(int,int,int)), this, SLOT(column_resize(int, int, int))); - //connect(_table_view->verticalScrollBar(), SIGNAL(sliderMoved()), this, SLOT(sliderMoved())); - connect(_search_edit, SIGNAL(editingFinished()), this, SLOT(search_changed())); -} - -ProtocolDock::~ProtocolDock() -{ -} - -void ProtocolDock::paintEvent(QPaintEvent *) -{ -// QStyleOption opt; -// opt.init(this); -// QPainter p(this); -// style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); -} - -void ProtocolDock::resizeEvent(QResizeEvent *event) -{ - int width = this->visibleRegion().boundingRect().width(); - width = width - _dn_layout->margin() * 2 - - _dn_search_layout->margin() * 2 - - _dn_search_layout->spacing() * 2 - - _pre_button->width()-_nxt_button->width(); - width = std::max(width, 0); - _search_edit->setMinimumWidth(width); - QScrollArea::resizeEvent(event); -} - -int ProtocolDock::decoder_name_cmp(const void *a, const void *b) -{ - return strcmp(((const srd_decoder*)a)->name, - ((const srd_decoder*)b)->name); -} - -bool ProtocolDock::sel_protocol(QString id) -{ - QString name; - GSList *l = g_slist_sort(g_slist_copy( - (GSList*)srd_decoder_list()), decoder_name_cmp); - for(; l; l = l->next) - { - const srd_decoder *const d = (srd_decoder*)l->data; - assert(d); - - const bool have_probes = (d->channels || d->opt_channels) != 0; - if (true == have_probes && - QString::fromUtf8(d->id) == id) { - name = QString::fromUtf8(d->name); - break; - } - } - g_slist_free(l); - - _protocol_combobox->setCurrentText(name); - if (_protocol_combobox->currentText() == name) - return true; - else - return false; -} - -void ProtocolDock::add_protocol() -{ - add_protocol(false); -} - -void ProtocolDock::add_protocol(bool silent) -{ - if (_session.get_device()->dev_inst()->mode != LOGIC) { - dialogs::DSMessageBox msg(this); - msg.mBox()->setText(tr("Protocol Analyzer")); - msg.mBox()->setInformativeText(tr("Protocol Analyzer is only valid in Digital Mode!")); - msg.mBox()->setStandardButtons(QMessageBox::Ok); - msg.mBox()->setIcon(QMessageBox::Warning); - msg.exec(); - } else { - srd_decoder *const decoder = - (srd_decoder*)(_protocol_combobox->itemData(_protocol_combobox->currentIndex())).value(); - if (_session.add_decoder(decoder, silent)) { - //std::list _sel_probes = dlg.get_sel_probes(); - //QMap & _options = dlg.get_options(); - //QMap _options_index = dlg.get_options_index(); - - QPushButton *_del_button = new QPushButton(_up_widget); - QPushButton *_set_button = new QPushButton(_up_widget); - _del_button->setFlat(true); - _del_button->setIcon(QIcon::fromTheme("protocol", - QIcon(":/icons/del.png"))); - _set_button->setFlat(true); - _set_button->setIcon(QIcon::fromTheme("protocol", - QIcon(":/icons/gear.png"))); - QLabel *_protocol_label = new QLabel(_up_widget); - QLabel *_progress_label = new QLabel(_up_widget); - - _del_button->setCheckable(true); - _protocol_label->setText(_protocol_combobox->currentText()); - - connect(_del_button, SIGNAL(clicked()), - this, SLOT(del_protocol())); - connect(_set_button, SIGNAL(clicked()), - this, SLOT(rst_protocol())); - - _del_button_list.push_back(_del_button); - _set_button_list.push_back(_set_button); - _protocol_label_list.push_back(_protocol_label); - _progress_label_list.push_back(_progress_label); - _protocol_index_list.push_back(_protocol_combobox->currentIndex()); - - QHBoxLayout *hori_layout = new QHBoxLayout(); - hori_layout->addWidget(_set_button); - hori_layout->addWidget(_del_button); - hori_layout->addWidget(_protocol_label); - hori_layout->addWidget(_progress_label); - hori_layout->addStretch(1); - _hori_layout_list.push_back(hori_layout); - _up_layout->insertLayout(_del_button_list.size(), hori_layout); - - // progress connection - const std::vector< boost::shared_ptr > decode_sigs( - _session.get_decode_signals()); - connect(decode_sigs.back().get(), SIGNAL(decoded_progress(int)), this, SLOT(decoded_progress(int))); - - protocol_updated(); - } - } -} - -void ProtocolDock::rst_protocol() -{ - int rst_index = 0; - for (QVector ::const_iterator i = _set_button_list.begin(); - i != _set_button_list.end(); i++) { - QPushButton *button = qobject_cast(sender()); - if ((*i) == button) { - //pv::decoder::DemoConfig dlg(this, _session.get_device(), _protocol_index_list.at(rst_index)); - //dlg.set_config(_session.get_decode_probes(rst_index), _session.get_decode_options_index(rst_index)); - //if (dlg.exec()) { - //std::list _sel_probes = dlg.get_sel_probes(); - //QMap & _options = dlg.get_options(); - //QMap _options_index = dlg.get_options_index(); - - //_session.rst_protocol_analyzer(rst_index, _sel_probes, _options, _options_index); - //} - _session.rst_decoder(rst_index); - break; - } - rst_index++; - } - protocol_updated(); -} - -void ProtocolDock::del_protocol() -{ - if (_del_all_button->isChecked()) { - _del_all_button->setChecked(false); - if (_hori_layout_list.size() > 0) { - int del_index = 0; - for (QVector ::const_iterator i = _hori_layout_list.begin(); - i != _hori_layout_list.end(); i++) { - _up_layout->removeItem((*i)); - delete (*i); - delete _del_button_list.at(del_index); - delete _set_button_list.at(del_index); - delete _protocol_label_list.at(del_index); - delete _progress_label_list.at(del_index); - - _session.remove_decode_signal(0); - del_index++; - } - _hori_layout_list.clear(); - _del_button_list.clear(); - _set_button_list.clear(); - _protocol_label_list.clear(); - _progress_label_list.clear(); - _protocol_index_list.clear(); - } else { - dialogs::DSMessageBox msg(NULL); - msg.mBox()->setText(tr("Protocol Analyzer")); - msg.mBox()->setInformativeText(tr("No Protocol Analyzer to delete!")); - msg.mBox()->setStandardButtons(QMessageBox::Ok); - msg.mBox()->setIcon(QMessageBox::Warning); - msg.exec(); - } - } else { - int del_index = 0; - for (QVector ::const_iterator i = _del_button_list.begin(); - i != _del_button_list.end(); i++) { - if ((*i)->isChecked()) { - _up_layout->removeItem(_hori_layout_list.at(del_index)); - - delete _hori_layout_list.at(del_index); - delete _del_button_list.at(del_index); - delete _set_button_list.at(del_index); - delete _protocol_label_list.at(del_index); - delete _progress_label_list.at(del_index); - - _hori_layout_list.remove(del_index); - _del_button_list.remove(del_index); - _set_button_list.remove(del_index); - _protocol_label_list.remove(del_index); - _progress_label_list.remove(del_index); - _protocol_index_list.remove(del_index); - - _session.remove_decode_signal(del_index); - break; - } - del_index++; - } - } - protocol_updated(); -} - -void ProtocolDock::del_all_protocol() -{ - if (_hori_layout_list.size() > 0) { - int del_index = 0; - for (QVector ::const_iterator i = _hori_layout_list.begin(); - i != _hori_layout_list.end(); i++) { - _up_layout->removeItem((*i)); - delete (*i); - delete _del_button_list.at(del_index); - delete _set_button_list.at(del_index); - delete _protocol_label_list.at(del_index); - delete _progress_label_list.at(del_index); - - _session.remove_decode_signal(0); - del_index++; - } - _hori_layout_list.clear(); - _del_button_list.clear(); - _set_button_list.clear(); - _protocol_label_list.clear(); - _progress_label_list.clear(); - _protocol_index_list.clear(); - - protocol_updated(); - } -} - -void ProtocolDock::decoded_progress(int progress) -{ - (void) progress; - - int pg = 0; - QString err=""; - const std::vector< boost::shared_ptr > decode_sigs( - _session.get_decode_signals()); - int index = 0; - BOOST_FOREACH(boost::shared_ptr d, decode_sigs) { - pg = d->get_progress(); - if (d->decoder()->out_of_memory()) - err = tr("(Out of Memory)"); - QString progress_str = QString::number(pg) + "%" + err; - if (pg == 100) - _progress_label_list.at(index)->setStyleSheet("color:green;"); - else - _progress_label_list.at(index)->setStyleSheet("color:red;"); - _progress_label_list.at(index)->setText(progress_str); - index++; - } - if (pg == 0 || pg % 10 == 1) - update_model(); -} - -void ProtocolDock::set_model() -{ - pv::dialogs::ProtocolList *protocollist_dlg = new pv::dialogs::ProtocolList(this, _session); - protocollist_dlg->exec(); - resize_table_view(_session.get_decoder_model()); - _model_proxy.setSourceModel(_session.get_decoder_model()); - search_done(); - - // clear mark_index of all DecoderStacks - const std::vector< boost::shared_ptr > decode_sigs( - _session.get_decode_signals()); - BOOST_FOREACH(boost::shared_ptr d, decode_sigs) { - d->decoder()->set_mark_index(-1); - } -} - -void ProtocolDock::update_model() -{ - pv::data::DecoderModel *decoder_model = _session.get_decoder_model(); - const std::vector< boost::shared_ptr > decode_sigs( - _session.get_decode_signals()); - if (decode_sigs.size() == 0) - decoder_model->setDecoderStack(NULL); - else if (!decoder_model->getDecoderStack()) - decoder_model->setDecoderStack(decode_sigs.at(0)->decoder()); - else { - unsigned int index = 0; - BOOST_FOREACH(const boost::shared_ptr d, decode_sigs) { - if (d->decoder() == decoder_model->getDecoderStack()) { - decoder_model->setDecoderStack(d->decoder()); - break; - } - index++; - } - if (index >= decode_sigs.size()) - decoder_model->setDecoderStack(decode_sigs.at(0)->decoder()); - } - _model_proxy.setSourceModel(decoder_model); - search_done(); - resize_table_view(decoder_model); -} - -void ProtocolDock::resize_table_view(data::DecoderModel* decoder_model) -{ - if (decoder_model->getDecoderStack()) { - for (int i = 0; i < decoder_model->columnCount(QModelIndex()) - 1; i++) { - _table_view->resizeColumnToContents(i); - if (_table_view->columnWidth(i) > 200) - _table_view->setColumnWidth(i, 200); - } - int top_row = _table_view->rowAt(0); - int bom_row = _table_view->rowAt(_table_view->height()); - if (bom_row >= top_row && top_row >= 0) { - for (int i = top_row; i <= bom_row; i++) - _table_view->resizeRowToContents(i); - } - } -} - -void ProtocolDock::item_clicked(const QModelIndex &index) -{ - pv::data::DecoderModel *decoder_model = _session.get_decoder_model(); - boost::shared_ptr decoder_stack = decoder_model->getDecoderStack(); - if (decoder_stack) { - pv::data::decode::Annotation ann; - if (decoder_stack->list_annotation(ann, index.column(), index.row())) { - const std::vector< boost::shared_ptr > decode_sigs( - _session.get_decode_signals()); - BOOST_FOREACH(boost::shared_ptr d, decode_sigs) { - d->decoder()->set_mark_index(-1); - } - decoder_stack->set_mark_index((ann.start_sample()+ann.end_sample())/2); - _session.show_region(ann.start_sample(), ann.end_sample(), false); - } - } - _table_view->resizeRowToContents(index.row()); - if (index.column() != _model_proxy.filterKeyColumn()) { - _model_proxy.setFilterKeyColumn(index.column()); - _model_proxy.setSourceModel(decoder_model); - search_done(); - } - QModelIndex filterIndex = _model_proxy.mapFromSource(index); - if (filterIndex.isValid()) { - _cur_search_index = filterIndex.row(); - } else { - if (_model_proxy.rowCount() == 0) { - _cur_search_index = -1; - } else { - uint64_t up = 0; - uint64_t dn = _model_proxy.rowCount() - 1; - do { - uint64_t md = (up + dn)/2; - QModelIndex curIndex = _model_proxy.mapToSource(_model_proxy.index(md,_model_proxy.filterKeyColumn())); - if (index.row() == curIndex.row()) { - _cur_search_index = md; - break; - } else if (md == up) { - if (curIndex.row() < index.row() && up < dn) { - QModelIndex nxtIndex = _model_proxy.mapToSource(_model_proxy.index(md+1,_model_proxy.filterKeyColumn())); - if (nxtIndex.row() < index.row()) - md++; - } - _cur_search_index = md + ((curIndex.row() < index.row()) ? 0.5 : -0.5); - break; - } else if (curIndex.row() < index.row()) { - up = md; - } else if (curIndex.row() > index.row()) { - dn = md; - } - }while(1); - } - } -} - -void ProtocolDock::column_resize(int index, int old_size, int new_size) -{ - (void)index; - (void)old_size; - (void)new_size; - pv::data::DecoderModel *decoder_model = _session.get_decoder_model(); - if (decoder_model->getDecoderStack()) { - int top_row = _table_view->rowAt(0); - int bom_row = _table_view->rowAt(_table_view->height()); - if (bom_row >= top_row && top_row >= 0) { - for (int i = top_row; i <= bom_row; i++) - _table_view->resizeRowToContents(i); - } - } -} - -void ProtocolDock::export_table_view() -{ - pv::dialogs::ProtocolExp *protocolexp_dlg = new pv::dialogs::ProtocolExp(this, _session); - protocolexp_dlg->exec(); -} - -void ProtocolDock::nav_table_view() -{ - uint64_t row_index = 0; - pv::data::DecoderModel *decoder_model = _session.get_decoder_model(); - boost::shared_ptr decoder_stack = decoder_model->getDecoderStack(); - if (decoder_stack) { - uint64_t offset = _view.offset() * (decoder_stack->samplerate() * _view.scale()); - std::map rows = decoder_stack->get_rows_lshow(); - int column = _model_proxy.filterKeyColumn(); - for (std::map::const_iterator i = rows.begin(); - i != rows.end(); i++) { - if ((*i).second && column-- == 0) { - row_index = decoder_stack->get_annotation_index((*i).first, offset); - break; - } - } - QModelIndex index = _model_proxy.mapToSource(_model_proxy.index(row_index, _model_proxy.filterKeyColumn())); - if(index.isValid()){ - _table_view->scrollTo(index); - _table_view->setCurrentIndex(index); - - pv::data::decode::Annotation ann; - decoder_stack->list_annotation(ann, index.column(), index.row()); - const std::vector< boost::shared_ptr > decode_sigs( - _session.get_decode_signals()); - BOOST_FOREACH(boost::shared_ptr d, decode_sigs) { - d->decoder()->set_mark_index(-1); - } - decoder_stack->set_mark_index((ann.start_sample()+ann.end_sample())/2); - _view.set_all_update(true); - _view.update(); - } - } -} - -void ProtocolDock::search_pre() -{ - search_update(); - // now the proxy only contains rows that match the name - // let's take the pre one and map it to the original model - if (_model_proxy.rowCount() == 0) { - _table_view->scrollToTop(); - _table_view->clearSelection(); - _matchs_label->setText(QString::number(0)); - _cur_search_index = -1; - return; - } - int i = 0; - uint64_t rowCount = _model_proxy.rowCount(); - QModelIndex matchingIndex; - pv::data::DecoderModel *decoder_model = _session.get_decoder_model(); - boost::shared_ptr decoder_stack = decoder_model->getDecoderStack(); - do { - _cur_search_index--; - if (_cur_search_index <= -1 || _cur_search_index >= _model_proxy.rowCount()) - _cur_search_index = _model_proxy.rowCount() - 1; - - matchingIndex = _model_proxy.mapToSource(_model_proxy.index(ceil(_cur_search_index),_model_proxy.filterKeyColumn())); - if (!decoder_stack || !matchingIndex.isValid()) - break; - i = 1; - uint64_t row = matchingIndex.row() + 1; - uint64_t col = matchingIndex.column(); - pv::data::decode::Annotation ann; - bool ann_valid; - while(i < _str_list.size()) { - QString nxt = _str_list.at(i); - do { - ann_valid = decoder_stack->list_annotation(ann, col, row); - row++; - }while(ann_valid && (ann.type() < 100 || ann.type() > 999)); - QString source = ann.annotations().at(0); - if (ann_valid && source.contains(nxt)) - i++; - else - break; - } - }while(i < _str_list.size() && --rowCount); - - if(i >= _str_list.size() && matchingIndex.isValid()){ - _table_view->scrollTo(matchingIndex); - _table_view->setCurrentIndex(matchingIndex); - _table_view->clicked(matchingIndex); - } else { - _table_view->scrollToTop(); - _table_view->clearSelection(); - _matchs_label->setText(QString::number(0)); - _cur_search_index = -1; - } -} - -void ProtocolDock::search_nxt() -{ - search_update(); - // now the proxy only contains rows that match the name - // let's take the pre one and map it to the original model - if (_model_proxy.rowCount() == 0) { - _table_view->scrollToTop(); - _table_view->clearSelection(); - _matchs_label->setText(QString::number(0)); - _cur_search_index = -1; - return; - } - int i = 0; - uint64_t rowCount = _model_proxy.rowCount(); - QModelIndex matchingIndex; - pv::data::DecoderModel *decoder_model = _session.get_decoder_model(); - boost::shared_ptr decoder_stack = decoder_model->getDecoderStack(); - do { - _cur_search_index++; - if (_cur_search_index < 0 || _cur_search_index >= _model_proxy.rowCount()) - _cur_search_index = 0; - - matchingIndex = _model_proxy.mapToSource(_model_proxy.index(floor(_cur_search_index),_model_proxy.filterKeyColumn())); - if (!decoder_stack || !matchingIndex.isValid()) - break; - i = 1; - uint64_t row = matchingIndex.row() + 1; - uint64_t col = matchingIndex.column(); - pv::data::decode::Annotation ann; - bool ann_valid; - while(i < _str_list.size()) { - QString nxt = _str_list.at(i); - do { - ann_valid = decoder_stack->list_annotation(ann, col, row); - row++; - }while(ann_valid && (ann.type() < 100 || ann.type() > 999)); - QString source = ann.annotations().at(0); - if (ann_valid && source.contains(nxt)) - i++; - else - break; - } - }while(i < _str_list.size() && --rowCount); - - if(i >= _str_list.size() && matchingIndex.isValid()){ - _table_view->scrollTo(matchingIndex); - _table_view->setCurrentIndex(matchingIndex); - _table_view->clicked(matchingIndex); - } else { - _table_view->scrollToTop(); - _table_view->clearSelection(); - _matchs_label->setText(QString::number(0)); - _cur_search_index = -1; - } -} - -void ProtocolDock::search_done() -{ - QString str = _search_edit->text().trimmed(); - QRegExp rx("(-)"); - _str_list = str.split(rx); - _model_proxy.setFilterFixedString(_str_list.first()); - if (_str_list.size() > 1) - _matchs_label->setText("..."); - else - _matchs_label->setText(QString::number(_model_proxy.rowCount())); -} - -void ProtocolDock::search_changed() -{ - _search_edited = true; - _matchs_label->setText("..."); -} - -void ProtocolDock::search_update() -{ - if (!_search_edited) - return; - - pv::data::DecoderModel *decoder_model = _session.get_decoder_model(); - boost::shared_ptr decoder_stack = decoder_model->getDecoderStack(); - if (!decoder_stack) - return; - - if (decoder_stack->list_annotation_size(_model_proxy.filterKeyColumn()) > ProgressRows) { - QFuture future; - future = QtConcurrent::run([&]{ - search_done(); - }); - Qt::WindowFlags flags = Qt::CustomizeWindowHint; - QProgressDialog dlg(tr("Searching..."), - tr("Cancel"),0,0,this,flags); - dlg.setWindowModality(Qt::WindowModal); - dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | - Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint); - dlg.setCancelButton(NULL); - - QFutureWatcher watcher; - watcher.setFuture(future); - connect(&watcher,SIGNAL(finished()),&dlg,SLOT(cancel())); - - dlg.exec(); - } else { - search_done(); - } - _search_edited = false; - //search_done(); -} - - -} // namespace dock -} // namespace pv +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2013 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "protocoldock.h" +#include "../sigsession.h" +#include "../view/decodetrace.h" +#include "../device/devinst.h" +#include "../data/decodermodel.h" +#include "../data/decoderstack.h" +#include "../dialogs/protocollist.h" +#include "../dialogs/protocolexp.h" +#include "../dialogs/dsmessagebox.h" +#include "../view/view.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace pv { +namespace dock { + +ProtocolDock::ProtocolDock(QWidget *parent, view::View &view, SigSession &session) : + QScrollArea(parent), + _session(session), + _view(view), + _cur_search_index(-1), + _search_edited(false), + _searching(false), + _add_silent(false) +{ + _up_widget = new QWidget(this); + + QHBoxLayout *hori_layout = new QHBoxLayout(); + + _add_button = new QPushButton(_up_widget); + _add_button->setFlat(true); + _del_all_button = new QPushButton(_up_widget); + _del_all_button->setFlat(true); + _del_all_button->setCheckable(true); + _protocol_combobox = new QComboBox(_up_widget); + + GSList *l = g_slist_sort(g_slist_copy( + (GSList*)srd_decoder_list()), decoder_name_cmp); + for(; l; l = l->next) + { + const srd_decoder *const d = (srd_decoder*)l->data; + assert(d); + + const bool have_probes = (d->channels || d->opt_channels) != 0; + if (true == have_probes) { + _protocol_combobox->addItem(QString::fromUtf8(d->name), qVariantFromValue(l->data)); + } + } + g_slist_free(l); + + hori_layout->addWidget(_add_button); + hori_layout->addWidget(_del_all_button); + hori_layout->addWidget(_protocol_combobox); + hori_layout->addStretch(1); + + connect(_add_button, SIGNAL(clicked()), + this, SLOT(add_protocol())); + connect(_del_all_button, SIGNAL(clicked()), + this, SLOT(del_protocol())); + + _up_layout = new QVBoxLayout(); + _up_layout->addLayout(hori_layout); + _up_layout->addStretch(1); + + _up_widget->setLayout(_up_layout); + _up_widget->setMinimumHeight(150); + +// this->setWidget(_widget); +// _widget->setGeometry(0, 0, sizeHint().width(), 500); +// _widget->setObjectName("protocolWidget"); + + _dn_widget = new QWidget(this); + + _dn_set_button = new QPushButton(_dn_widget); + _dn_set_button->setFlat(true); + connect(_dn_set_button, SIGNAL(clicked()), + this, SLOT(set_model())); + + _dn_save_button = new QPushButton(_dn_widget); + _dn_save_button->setFlat(true); + connect(_dn_save_button, SIGNAL(clicked()), + this, SLOT(export_table_view())); + + _dn_nav_button = new QPushButton(_dn_widget); + _dn_nav_button->setFlat(true); + connect(_dn_nav_button, SIGNAL(clicked()), + this, SLOT(nav_table_view())); + + QHBoxLayout *dn_title_layout = new QHBoxLayout(); + _dn_title_label = new QLabel(_dn_widget); + dn_title_layout->addWidget(_dn_set_button, 0, Qt::AlignLeft); + dn_title_layout->addWidget(_dn_save_button, 0, Qt::AlignLeft); + dn_title_layout->addWidget(_dn_title_label, 1, Qt::AlignLeft); + dn_title_layout->addWidget(_dn_nav_button, 0, Qt::AlignRight); + //dn_title_layout->addStretch(1); + + _table_view = new QTableView(_dn_widget); + _table_view->setModel(_session.get_decoder_model()); + _table_view->setAlternatingRowColors(true); + _table_view->setShowGrid(false); + _table_view->horizontalHeader()->setStretchLastSection(true); + _table_view->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); + _table_view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + + _pre_button = new QPushButton(_dn_widget); + _nxt_button = new QPushButton(_dn_widget); + connect(_pre_button, SIGNAL(clicked()), + this, SLOT(search_pre())); + connect(_nxt_button, SIGNAL(clicked()), + this, SLOT(search_nxt())); + + _search_button = new QPushButton(this); + _search_button->setFixedWidth(_search_button->height()); + _search_button->setDisabled(true); + _search_edit = new QLineEdit(_dn_widget); + _search_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + QHBoxLayout *search_layout = new QHBoxLayout(); + search_layout->addWidget(_search_button); + search_layout->addStretch(1); + search_layout->setContentsMargins(0, 0, 0, 0); + _search_edit->setLayout(search_layout); + _search_edit->setTextMargins(_search_button->width(), 0, 0, 0); + + _dn_search_layout = new QHBoxLayout(); + _dn_search_layout->addWidget(_pre_button, 0, Qt::AlignLeft); + _dn_search_layout->addWidget(_search_edit, 1, Qt::AlignLeft); + _dn_search_layout->addWidget(_nxt_button, 0, Qt::AlignRight); + + _matchs_label = new QLabel(_dn_widget); + _matchs_title_label = new QLabel(_dn_widget); + QHBoxLayout *dn_match_layout = new QHBoxLayout(); + dn_match_layout->addWidget(_matchs_title_label, 0, Qt::AlignLeft); + dn_match_layout->addWidget(_matchs_label, 0, Qt::AlignLeft); + dn_match_layout->addStretch(1); + + _dn_layout = new QVBoxLayout(); + _dn_layout->addLayout(dn_title_layout); + _dn_layout->addLayout(_dn_search_layout); + _dn_layout->addLayout(dn_match_layout); + _dn_layout->addWidget(_table_view); + + _dn_widget->setLayout(_dn_layout); + _dn_widget->setMinimumHeight(350); + + _split_widget = new QSplitter(this); + _split_widget->insertWidget(0, _up_widget); + _split_widget->insertWidget(1, _dn_widget); + _split_widget->setOrientation(Qt::Vertical); + _split_widget->setCollapsible(0, false); + _split_widget->setCollapsible(1, false); + //_split_widget->setStretchFactor(1, 1); + //_split_widget + + this->setWidgetResizable(true); + this->setWidget(_split_widget); + //_split_widget->setGeometry(0, 0, sizeHint().width(), 500); + _split_widget->setObjectName("protocolWidget"); + + connect(&_session, SIGNAL(decode_done()), this, SLOT(update_model())); + connect(this, SIGNAL(protocol_updated()), this, SLOT(update_model())); + connect(_table_view, SIGNAL(clicked(QModelIndex)), this, SLOT(item_clicked(QModelIndex))); + connect(_table_view->horizontalHeader(), SIGNAL(sectionResized(int,int,int)), this, SLOT(column_resize(int, int, int))); + //connect(_table_view->verticalScrollBar(), SIGNAL(sliderMoved()), this, SLOT(sliderMoved())); + connect(_search_edit, SIGNAL(editingFinished()), this, SLOT(search_changed())); + + retranslateUi(); +} + +ProtocolDock::~ProtocolDock() +{ +} + +void ProtocolDock::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + retranslateUi(); + else if (event->type() == QEvent::StyleChange) + reStyle(); + QScrollArea::changeEvent(event); +} + +void ProtocolDock::retranslateUi() +{ + _search_edit->setPlaceholderText(tr("search")); + _matchs_title_label->setText(tr("Matching Items:")); + _dn_title_label->setText(tr("Protocol List Viewer")); +} + +void ProtocolDock::reStyle() +{ + QString iconPath = ":/icons/" + qApp->property("Style").toString(); + + _add_button->setIcon(QIcon(iconPath+"/add.png")); + _del_all_button->setIcon(QIcon(iconPath+"/del.png")); + _dn_set_button->setIcon(QIcon(iconPath+"/gear.png")); + _dn_save_button->setIcon(QIcon(iconPath+"/save.png")); + _dn_nav_button->setIcon(QIcon(iconPath+"/nav.png")); + _pre_button->setIcon(QIcon(iconPath+"/pre.png")); + _nxt_button->setIcon(QIcon(iconPath+"/next.png")); + _search_button->setIcon(QIcon(iconPath+"/search.png")); + + for (QVector ::const_iterator i = _del_button_list.begin(); + i != _del_button_list.end(); i++) + (*i)->setIcon(QIcon(iconPath+"/del.png")); + + for (QVector ::const_iterator i = _set_button_list.begin(); + i != _set_button_list.end(); i++) + (*i)->setIcon(QIcon(iconPath+"/gear.png")); +} + +void ProtocolDock::paintEvent(QPaintEvent *) +{ +// QStyleOption opt; +// opt.init(this); +// QPainter p(this); +// style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); +} + +void ProtocolDock::resizeEvent(QResizeEvent *event) +{ + int width = this->visibleRegion().boundingRect().width(); + width = width - _dn_layout->margin() * 2 - + _dn_search_layout->margin() * 2 - + _dn_search_layout->spacing() * 2 - + _pre_button->width()-_nxt_button->width(); + width = std::max(width, 0); + _search_edit->setMinimumWidth(width); + QScrollArea::resizeEvent(event); +} + +int ProtocolDock::decoder_name_cmp(const void *a, const void *b) +{ + return strcmp(((const srd_decoder*)a)->name, + ((const srd_decoder*)b)->name); +} + +bool ProtocolDock::sel_protocol(QString id) +{ + QString name; + GSList *l = g_slist_sort(g_slist_copy( + (GSList*)srd_decoder_list()), decoder_name_cmp); + for(; l; l = l->next) + { + const srd_decoder *const d = (srd_decoder*)l->data; + assert(d); + + const bool have_probes = (d->channels || d->opt_channels) != 0; + if (true == have_probes && + QString::fromUtf8(d->id) == id) { + name = QString::fromUtf8(d->name); + break; + } + } + g_slist_free(l); + + _protocol_combobox->setCurrentText(name); + if (_protocol_combobox->currentText() == name) + return true; + else + return false; +} + +void ProtocolDock::add_protocol() +{ + add_protocol(false); +} + +void ProtocolDock::add_protocol(bool silent) +{ + if (_session.get_device()->dev_inst()->mode != LOGIC) { + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Protocol Analyzer")); + msg.mBox()->setInformativeText(tr("Protocol Analyzer is only valid in Digital Mode!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); + msg.exec(); + } else { + srd_decoder *const decoder = + (srd_decoder*)(_protocol_combobox->itemData(_protocol_combobox->currentIndex())).value(); + if (_session.add_decoder(decoder, silent)) { + //std::list _sel_probes = dlg.get_sel_probes(); + //QMap & _options = dlg.get_options(); + //QMap _options_index = dlg.get_options_index(); + + QString iconPath = ":/icons/" + qApp->property("Style").toString(); + QPushButton *_del_button = new QPushButton(_up_widget); + QPushButton *_set_button = new QPushButton(_up_widget); + _del_button->setFlat(true); + _del_button->setIcon(QIcon(iconPath+"/del.png")); + _set_button->setFlat(true); + _set_button->setIcon(QIcon(iconPath+"/gear.png")); + QLabel *_protocol_label = new QLabel(_up_widget); + QLabel *_progress_label = new QLabel(_up_widget); + + _del_button->setCheckable(true); + _protocol_label->setText(_protocol_combobox->currentText()); + + connect(_del_button, SIGNAL(clicked()), + this, SLOT(del_protocol())); + connect(_set_button, SIGNAL(clicked()), + this, SLOT(rst_protocol())); + + _del_button_list.push_back(_del_button); + _set_button_list.push_back(_set_button); + _protocol_label_list.push_back(_protocol_label); + _progress_label_list.push_back(_progress_label); + _protocol_index_list.push_back(_protocol_combobox->currentIndex()); + + QHBoxLayout *hori_layout = new QHBoxLayout(); + hori_layout->addWidget(_set_button); + hori_layout->addWidget(_del_button); + hori_layout->addWidget(_protocol_label); + hori_layout->addWidget(_progress_label); + hori_layout->addStretch(1); + _hori_layout_list.push_back(hori_layout); + _up_layout->insertLayout(_del_button_list.size(), hori_layout); + + // progress connection + const std::vector< boost::shared_ptr > decode_sigs( + _session.get_decode_signals()); + connect(decode_sigs.back().get(), SIGNAL(decoded_progress(int)), this, SLOT(decoded_progress(int))); + + protocol_updated(); + } + } +} + +void ProtocolDock::rst_protocol() +{ + int rst_index = 0; + for (QVector ::const_iterator i = _set_button_list.begin(); + i != _set_button_list.end(); i++) { + QPushButton *button = qobject_cast(sender()); + if ((*i) == button) { + //pv::decoder::DemoConfig dlg(this, _session.get_device(), _protocol_index_list.at(rst_index)); + //dlg.set_config(_session.get_decode_probes(rst_index), _session.get_decode_options_index(rst_index)); + //if (dlg.exec()) { + //std::list _sel_probes = dlg.get_sel_probes(); + //QMap & _options = dlg.get_options(); + //QMap _options_index = dlg.get_options_index(); + + //_session.rst_protocol_analyzer(rst_index, _sel_probes, _options, _options_index); + //} + _session.rst_decoder(rst_index); + break; + } + rst_index++; + } + protocol_updated(); +} + +void ProtocolDock::del_protocol() +{ + if (_del_all_button->isChecked()) { + _del_all_button->setChecked(false); + if (_hori_layout_list.size() > 0) { + int del_index = 0; + for (QVector ::const_iterator i = _hori_layout_list.begin(); + i != _hori_layout_list.end(); i++) { + _up_layout->removeItem((*i)); + delete (*i); + delete _del_button_list.at(del_index); + delete _set_button_list.at(del_index); + delete _protocol_label_list.at(del_index); + delete _progress_label_list.at(del_index); + + _session.remove_decode_signal(0); + del_index++; + } + _hori_layout_list.clear(); + _del_button_list.clear(); + _set_button_list.clear(); + _protocol_label_list.clear(); + _progress_label_list.clear(); + _protocol_index_list.clear(); + } else { + dialogs::DSMessageBox msg(NULL); + msg.mBox()->setText(tr("Protocol Analyzer")); + msg.mBox()->setInformativeText(tr("No Protocol Analyzer to delete!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); + msg.exec(); + } + } else { + int del_index = 0; + for (QVector ::const_iterator i = _del_button_list.begin(); + i != _del_button_list.end(); i++) { + if ((*i)->isChecked()) { + _up_layout->removeItem(_hori_layout_list.at(del_index)); + + delete _hori_layout_list.at(del_index); + delete _del_button_list.at(del_index); + delete _set_button_list.at(del_index); + delete _protocol_label_list.at(del_index); + delete _progress_label_list.at(del_index); + + _hori_layout_list.remove(del_index); + _del_button_list.remove(del_index); + _set_button_list.remove(del_index); + _protocol_label_list.remove(del_index); + _progress_label_list.remove(del_index); + _protocol_index_list.remove(del_index); + + _session.remove_decode_signal(del_index); + break; + } + del_index++; + } + } + protocol_updated(); +} + +void ProtocolDock::del_all_protocol() +{ + if (_hori_layout_list.size() > 0) { + int del_index = 0; + for (QVector ::const_iterator i = _hori_layout_list.begin(); + i != _hori_layout_list.end(); i++) { + _up_layout->removeItem((*i)); + delete (*i); + delete _del_button_list.at(del_index); + delete _set_button_list.at(del_index); + delete _protocol_label_list.at(del_index); + delete _progress_label_list.at(del_index); + + _session.remove_decode_signal(0); + del_index++; + } + _hori_layout_list.clear(); + _del_button_list.clear(); + _set_button_list.clear(); + _protocol_label_list.clear(); + _progress_label_list.clear(); + _protocol_index_list.clear(); + + protocol_updated(); + } +} + +void ProtocolDock::decoded_progress(int progress) +{ + (void) progress; + + int pg = 0; + QString err=""; + const std::vector< boost::shared_ptr > decode_sigs( + _session.get_decode_signals()); + int index = 0; + BOOST_FOREACH(boost::shared_ptr d, decode_sigs) { + pg = d->get_progress(); + if (d->decoder()->out_of_memory()) + err = tr("(Out of Memory)"); + QString progress_str = QString::number(pg) + "%" + err; + if (pg == 100) + _progress_label_list.at(index)->setStyleSheet("color:green;"); + else + _progress_label_list.at(index)->setStyleSheet("color:red;"); + _progress_label_list.at(index)->setText(progress_str); + index++; + } + if (pg == 0 || pg % 10 == 1) + update_model(); +} + +void ProtocolDock::set_model() +{ + pv::dialogs::ProtocolList *protocollist_dlg = new pv::dialogs::ProtocolList(this, _session); + protocollist_dlg->exec(); + resize_table_view(_session.get_decoder_model()); + _model_proxy.setSourceModel(_session.get_decoder_model()); + search_done(); + + // clear mark_index of all DecoderStacks + const std::vector< boost::shared_ptr > decode_sigs( + _session.get_decode_signals()); + BOOST_FOREACH(boost::shared_ptr d, decode_sigs) { + d->decoder()->set_mark_index(-1); + } +} + +void ProtocolDock::update_model() +{ + pv::data::DecoderModel *decoder_model = _session.get_decoder_model(); + const std::vector< boost::shared_ptr > decode_sigs( + _session.get_decode_signals()); + if (decode_sigs.size() == 0) + decoder_model->setDecoderStack(NULL); + else if (!decoder_model->getDecoderStack()) + decoder_model->setDecoderStack(decode_sigs.at(0)->decoder()); + else { + unsigned int index = 0; + BOOST_FOREACH(const boost::shared_ptr d, decode_sigs) { + if (d->decoder() == decoder_model->getDecoderStack()) { + decoder_model->setDecoderStack(d->decoder()); + break; + } + index++; + } + if (index >= decode_sigs.size()) + decoder_model->setDecoderStack(decode_sigs.at(0)->decoder()); + } + _model_proxy.setSourceModel(decoder_model); + search_done(); + resize_table_view(decoder_model); +} + +void ProtocolDock::resize_table_view(data::DecoderModel* decoder_model) +{ + if (decoder_model->getDecoderStack()) { + for (int i = 0; i < decoder_model->columnCount(QModelIndex()) - 1; i++) { + _table_view->resizeColumnToContents(i); + if (_table_view->columnWidth(i) > 200) + _table_view->setColumnWidth(i, 200); + } + int top_row = _table_view->rowAt(0); + int bom_row = _table_view->rowAt(_table_view->height()); + if (bom_row >= top_row && top_row >= 0) { + for (int i = top_row; i <= bom_row; i++) + _table_view->resizeRowToContents(i); + } + } +} + +void ProtocolDock::item_clicked(const QModelIndex &index) +{ + pv::data::DecoderModel *decoder_model = _session.get_decoder_model(); + boost::shared_ptr decoder_stack = decoder_model->getDecoderStack(); + if (decoder_stack) { + pv::data::decode::Annotation ann; + if (decoder_stack->list_annotation(ann, index.column(), index.row())) { + const std::vector< boost::shared_ptr > decode_sigs( + _session.get_decode_signals()); + BOOST_FOREACH(boost::shared_ptr d, decode_sigs) { + d->decoder()->set_mark_index(-1); + } + decoder_stack->set_mark_index((ann.start_sample()+ann.end_sample())/2); + _session.show_region(ann.start_sample(), ann.end_sample(), false); + } + } + _table_view->resizeRowToContents(index.row()); + if (index.column() != _model_proxy.filterKeyColumn()) { + _model_proxy.setFilterKeyColumn(index.column()); + _model_proxy.setSourceModel(decoder_model); + search_done(); + } + QModelIndex filterIndex = _model_proxy.mapFromSource(index); + if (filterIndex.isValid()) { + _cur_search_index = filterIndex.row(); + } else { + if (_model_proxy.rowCount() == 0) { + _cur_search_index = -1; + } else { + uint64_t up = 0; + uint64_t dn = _model_proxy.rowCount() - 1; + do { + uint64_t md = (up + dn)/2; + QModelIndex curIndex = _model_proxy.mapToSource(_model_proxy.index(md,_model_proxy.filterKeyColumn())); + if (index.row() == curIndex.row()) { + _cur_search_index = md; + break; + } else if (md == up) { + if (curIndex.row() < index.row() && up < dn) { + QModelIndex nxtIndex = _model_proxy.mapToSource(_model_proxy.index(md+1,_model_proxy.filterKeyColumn())); + if (nxtIndex.row() < index.row()) + md++; + } + _cur_search_index = md + ((curIndex.row() < index.row()) ? 0.5 : -0.5); + break; + } else if (curIndex.row() < index.row()) { + up = md; + } else if (curIndex.row() > index.row()) { + dn = md; + } + }while(1); + } + } +} + +void ProtocolDock::column_resize(int index, int old_size, int new_size) +{ + (void)index; + (void)old_size; + (void)new_size; + pv::data::DecoderModel *decoder_model = _session.get_decoder_model(); + if (decoder_model->getDecoderStack()) { + int top_row = _table_view->rowAt(0); + int bom_row = _table_view->rowAt(_table_view->height()); + if (bom_row >= top_row && top_row >= 0) { + for (int i = top_row; i <= bom_row; i++) + _table_view->resizeRowToContents(i); + } + } +} + +void ProtocolDock::export_table_view() +{ + pv::dialogs::ProtocolExp *protocolexp_dlg = new pv::dialogs::ProtocolExp(this, _session); + protocolexp_dlg->exec(); +} + +void ProtocolDock::nav_table_view() +{ + uint64_t row_index = 0; + pv::data::DecoderModel *decoder_model = _session.get_decoder_model(); + boost::shared_ptr decoder_stack = decoder_model->getDecoderStack(); + if (decoder_stack) { + uint64_t offset = _view.offset() * (decoder_stack->samplerate() * _view.scale()); + std::map rows = decoder_stack->get_rows_lshow(); + int column = _model_proxy.filterKeyColumn(); + for (std::map::const_iterator i = rows.begin(); + i != rows.end(); i++) { + if ((*i).second && column-- == 0) { + row_index = decoder_stack->get_annotation_index((*i).first, offset); + break; + } + } + QModelIndex index = _model_proxy.mapToSource(_model_proxy.index(row_index, _model_proxy.filterKeyColumn())); + if(index.isValid()){ + _table_view->scrollTo(index); + _table_view->setCurrentIndex(index); + + pv::data::decode::Annotation ann; + decoder_stack->list_annotation(ann, index.column(), index.row()); + const std::vector< boost::shared_ptr > decode_sigs( + _session.get_decode_signals()); + BOOST_FOREACH(boost::shared_ptr d, decode_sigs) { + d->decoder()->set_mark_index(-1); + } + decoder_stack->set_mark_index((ann.start_sample()+ann.end_sample())/2); + _view.set_all_update(true); + _view.update(); + } + } +} + +void ProtocolDock::search_pre() +{ + search_update(); + // now the proxy only contains rows that match the name + // let's take the pre one and map it to the original model + if (_model_proxy.rowCount() == 0) { + _table_view->scrollToTop(); + _table_view->clearSelection(); + _matchs_label->setText(QString::number(0)); + _cur_search_index = -1; + return; + } + int i = 0; + uint64_t rowCount = _model_proxy.rowCount(); + QModelIndex matchingIndex; + pv::data::DecoderModel *decoder_model = _session.get_decoder_model(); + boost::shared_ptr decoder_stack = decoder_model->getDecoderStack(); + do { + _cur_search_index--; + if (_cur_search_index <= -1 || _cur_search_index >= _model_proxy.rowCount()) + _cur_search_index = _model_proxy.rowCount() - 1; + + matchingIndex = _model_proxy.mapToSource(_model_proxy.index(ceil(_cur_search_index),_model_proxy.filterKeyColumn())); + if (!decoder_stack || !matchingIndex.isValid()) + break; + i = 1; + uint64_t row = matchingIndex.row() + 1; + uint64_t col = matchingIndex.column(); + pv::data::decode::Annotation ann; + bool ann_valid; + while(i < _str_list.size()) { + QString nxt = _str_list.at(i); + do { + ann_valid = decoder_stack->list_annotation(ann, col, row); + row++; + }while(ann_valid && (ann.type() < 100 || ann.type() > 999)); + QString source = ann.annotations().at(0); + if (ann_valid && source.contains(nxt)) + i++; + else + break; + } + }while(i < _str_list.size() && --rowCount); + + if(i >= _str_list.size() && matchingIndex.isValid()){ + _table_view->scrollTo(matchingIndex); + _table_view->setCurrentIndex(matchingIndex); + _table_view->clicked(matchingIndex); + } else { + _table_view->scrollToTop(); + _table_view->clearSelection(); + _matchs_label->setText(QString::number(0)); + _cur_search_index = -1; + } +} + +void ProtocolDock::search_nxt() +{ + search_update(); + // now the proxy only contains rows that match the name + // let's take the pre one and map it to the original model + if (_model_proxy.rowCount() == 0) { + _table_view->scrollToTop(); + _table_view->clearSelection(); + _matchs_label->setText(QString::number(0)); + _cur_search_index = -1; + return; + } + int i = 0; + uint64_t rowCount = _model_proxy.rowCount(); + QModelIndex matchingIndex; + pv::data::DecoderModel *decoder_model = _session.get_decoder_model(); + boost::shared_ptr decoder_stack = decoder_model->getDecoderStack(); + do { + _cur_search_index++; + if (_cur_search_index < 0 || _cur_search_index >= _model_proxy.rowCount()) + _cur_search_index = 0; + + matchingIndex = _model_proxy.mapToSource(_model_proxy.index(floor(_cur_search_index),_model_proxy.filterKeyColumn())); + if (!decoder_stack || !matchingIndex.isValid()) + break; + i = 1; + uint64_t row = matchingIndex.row() + 1; + uint64_t col = matchingIndex.column(); + pv::data::decode::Annotation ann; + bool ann_valid; + while(i < _str_list.size()) { + QString nxt = _str_list.at(i); + do { + ann_valid = decoder_stack->list_annotation(ann, col, row); + row++; + }while(ann_valid && (ann.type() < 100 || ann.type() > 999)); + QString source = ann.annotations().at(0); + if (ann_valid && source.contains(nxt)) + i++; + else + break; + } + }while(i < _str_list.size() && --rowCount); + + if(i >= _str_list.size() && matchingIndex.isValid()){ + _table_view->scrollTo(matchingIndex); + _table_view->setCurrentIndex(matchingIndex); + _table_view->clicked(matchingIndex); + } else { + _table_view->scrollToTop(); + _table_view->clearSelection(); + _matchs_label->setText(QString::number(0)); + _cur_search_index = -1; + } +} + +void ProtocolDock::search_done() +{ + QString str = _search_edit->text().trimmed(); + QRegExp rx("(-)"); + _str_list = str.split(rx); + _model_proxy.setFilterFixedString(_str_list.first()); + if (_str_list.size() > 1) + _matchs_label->setText("..."); + else + _matchs_label->setText(QString::number(_model_proxy.rowCount())); +} + +void ProtocolDock::search_changed() +{ + _search_edited = true; + _matchs_label->setText("..."); +} + +void ProtocolDock::search_update() +{ + if (!_search_edited) + return; + + pv::data::DecoderModel *decoder_model = _session.get_decoder_model(); + boost::shared_ptr decoder_stack = decoder_model->getDecoderStack(); + if (!decoder_stack) + return; + + if (decoder_stack->list_annotation_size(_model_proxy.filterKeyColumn()) > ProgressRows) { + QFuture future; + future = QtConcurrent::run([&]{ + search_done(); + }); + Qt::WindowFlags flags = Qt::CustomizeWindowHint; + QProgressDialog dlg(tr("Searching..."), + tr("Cancel"),0,0,this,flags); + dlg.setWindowModality(Qt::WindowModal); + dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | + Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint); + dlg.setCancelButton(NULL); + + QFutureWatcher watcher; + connect(&watcher,SIGNAL(finished()),&dlg,SLOT(cancel())); + watcher.setFuture(future); + + dlg.exec(); + } else { + search_done(); + } + _search_edited = false; + //search_done(); +} + + +} // namespace dock +} // namespace pv diff --git a/DSView/pv/dock/protocoldock.h b/DSView/pv/dock/protocoldock.h old mode 100644 new mode 100755 index 8fb7d600ce734c8f5a3d7e2ab8682e10f6e5b812..f5bc4534e8d47dfa1db2448ec51e009bdb4ac9d9 --- a/DSView/pv/dock/protocoldock.h +++ b/DSView/pv/dock/protocoldock.h @@ -1,145 +1,153 @@ -/* - * This file is part of the DSView project. - * DSView is based on PulseView. - * - * Copyright (C) 2013 DreamSourceLab - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#ifndef DSVIEW_PV_PROTOCOLDOCK_H -#define DSVIEW_PV_PROTOCOLDOCK_H - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "../data/decodermodel.h" - -namespace pv { - -class SigSession; - -namespace data { -class DecoderModel; -} - -namespace view { -class View; -} - -namespace dock { - -class ProtocolDock : public QScrollArea -{ - Q_OBJECT - -public: - static const uint64_t ProgressRows = 100000; - -public: - ProtocolDock(QWidget *parent, view::View &view, SigSession &session); - ~ProtocolDock(); - - void del_all_protocol(); - bool sel_protocol(QString name); - void add_protocol(bool silent); - -protected: - void paintEvent(QPaintEvent *); - void resizeEvent(QResizeEvent *); - -signals: - void protocol_updated(); - -private slots: - void add_protocol(); - void rst_protocol(); - void del_protocol(); - void decoded_progress(int progress); - void set_model(); - void update_model(); - void export_table_view(); - void nav_table_view(); - void item_clicked(const QModelIndex &index); - void column_resize(int index, int old_size, int new_size); - void search_pre(); - void search_nxt(); - void search_done(); - void search_changed(); - void search_update(); - -private: - static int decoder_name_cmp(const void *a, const void *b); - void resize_table_view(data::DecoderModel *decoder_model); - -private: - SigSession &_session; - view::View &_view; - QSortFilterProxyModel _model_proxy; - double _cur_search_index; - QStringList _str_list; - - QSplitter *_split_widget; - QWidget *_up_widget; - QWidget *_dn_widget; - QTableView *_table_view; - QPushButton *_pre_button; - QPushButton *_nxt_button; - QLineEdit *_search_edit; - QHBoxLayout *_dn_search_layout; - QVBoxLayout *_dn_layout; - QLabel *_matchs_label; - - QPushButton *_add_button; - QPushButton *_del_all_button; - QComboBox *_protocol_combobox; - QVector _del_button_list; - QVector _set_button_list; - QVector _protocol_label_list; - QVector _progress_label_list; - QVector _protocol_index_list; - QVector _hori_layout_list; - QVBoxLayout *_up_layout; - - QPushButton *_dn_set_button; - QPushButton *_dn_save_button; - QPushButton *_dn_nav_button; - - mutable boost::mutex _search_mutex; - bool _search_edited; - bool _searching; - - bool _add_silent; -}; - -} // namespace dock -} // namespace pv - -#endif // DSVIEW_PV_PROTOCOLDOCK_H +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2013 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef DSVIEW_PV_PROTOCOLDOCK_H +#define DSVIEW_PV_PROTOCOLDOCK_H + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../data/decodermodel.h" + +namespace pv { + +class SigSession; + +namespace data { +class DecoderModel; +} + +namespace view { +class View; +} + +namespace dock { + +class ProtocolDock : public QScrollArea +{ + Q_OBJECT + +public: + static const uint64_t ProgressRows = 100000; + +public: + ProtocolDock(QWidget *parent, view::View &view, SigSession &session); + ~ProtocolDock(); + + void del_all_protocol(); + bool sel_protocol(QString name); + void add_protocol(bool silent); +private: + void changeEvent(QEvent *event); + void retranslateUi(); + void reStyle(); + +protected: + void paintEvent(QPaintEvent *); + void resizeEvent(QResizeEvent *); + +signals: + void protocol_updated(); + +private slots: + void add_protocol(); + void rst_protocol(); + void del_protocol(); + void decoded_progress(int progress); + void set_model(); + void update_model(); + void export_table_view(); + void nav_table_view(); + void item_clicked(const QModelIndex &index); + void column_resize(int index, int old_size, int new_size); + void search_pre(); + void search_nxt(); + void search_done(); + void search_changed(); + void search_update(); + +private: + static int decoder_name_cmp(const void *a, const void *b); + void resize_table_view(data::DecoderModel *decoder_model); + +private: + SigSession &_session; + view::View &_view; + QSortFilterProxyModel _model_proxy; + double _cur_search_index; + QStringList _str_list; + + QSplitter *_split_widget; + QWidget *_up_widget; + QWidget *_dn_widget; + QTableView *_table_view; + QPushButton *_pre_button; + QPushButton *_nxt_button; + QLineEdit *_search_edit; + QHBoxLayout *_dn_search_layout; + QVBoxLayout *_dn_layout; + QLabel *_matchs_label; + QLabel *_matchs_title_label; + QLabel *_dn_title_label; + + QPushButton *_add_button; + QPushButton *_del_all_button; + QComboBox *_protocol_combobox; + QVector _del_button_list; + QVector _set_button_list; + QVector _protocol_label_list; + QVector _progress_label_list; + QVector _protocol_index_list; + QVector _hori_layout_list; + QVBoxLayout *_up_layout; + + QPushButton *_dn_set_button; + QPushButton *_dn_save_button; + QPushButton *_dn_nav_button; + + QPushButton *_search_button; + + mutable boost::mutex _search_mutex; + bool _search_edited; + bool _searching; + + bool _add_silent; +}; + +} // namespace dock +} // namespace pv + +#endif // DSVIEW_PV_PROTOCOLDOCK_H diff --git a/DSView/pv/dock/searchdock.cpp b/DSView/pv/dock/searchdock.cpp old mode 100644 new mode 100755 index d702373e91eb0f9c2750ab67eb796498378b7d01..60c0f5941aa081d59fdfcbf16cdd310e8082e7ad --- a/DSView/pv/dock/searchdock.cpp +++ b/DSView/pv/dock/searchdock.cpp @@ -1,258 +1,275 @@ -/* - * This file is part of the DSView project. - * DSView is based on PulseView. - * - * Copyright (C) 2013 DreamSourceLab - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "searchdock.h" -#include "../sigsession.h" -#include "../view/cursor.h" -#include "../view/view.h" -#include "../view/timemarker.h" -#include "../view/ruler.h" -#include "../dialogs/search.h" -#include "../data/snapshot.h" -#include "../data/logicsnapshot.h" -#include "../device/devinst.h" -#include "../dialogs/dsmessagebox.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace pv { -namespace dock { - -using namespace pv::view; -using namespace pv::widgets; - -SearchDock::SearchDock(QWidget *parent, View &view, SigSession &session) : - QWidget(parent), - _session(session), - _view(view) -{ - connect(&_pre_button, SIGNAL(clicked()), - this, SLOT(on_previous())); - connect(&_nxt_button, SIGNAL(clicked()), - this, SLOT(on_next())); - - _pre_button.setIcon(QIcon::fromTheme("searchDock", - QIcon(":/icons/pre.png"))); - _nxt_button.setIcon(QIcon::fromTheme("searchDock", - QIcon(":/icons/next.png"))); - - _search_button = new QPushButton(this); - _search_button->setIcon(QIcon::fromTheme("searchDock", - QIcon(":/icons/search.png"))); - _search_button->setFixedWidth(_search_button->height()); - _search_button->setDisabled(true); - - QLineEdit *_search_parent = new QLineEdit(this); - _search_parent->setVisible(false); - _search_value = new FakeLineEdit(_search_parent); - _search_value->setPlaceholderText(tr("search")); - - QHBoxLayout *search_layout = new QHBoxLayout(); - search_layout->addWidget(_search_button); - search_layout->addStretch(); - search_layout->setContentsMargins(0, 0, 0, 0); - _search_value->setLayout(search_layout); - _search_value->setTextMargins(_search_button->width(), 0, 0, 0); - _search_value->setReadOnly(true); - - connect(_search_value, SIGNAL(trigger()), this, SLOT(on_set())); - - QHBoxLayout *layout = new QHBoxLayout(); - layout->addStretch(1); - layout->addWidget(&_pre_button); - layout->addWidget(_search_value); - layout->addWidget(&_nxt_button); - layout->addStretch(1); - - setLayout(layout); -} - -SearchDock::~SearchDock() -{ -} - -void SearchDock::paintEvent(QPaintEvent *) -{ -// QStyleOption opt; -// opt.init(this); -// QPainter p(this); -// style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); -} - -void SearchDock::on_previous() -{ - bool ret; - int64_t last_pos; - bool last_hit; - const boost::shared_ptr snapshot(_session.get_snapshot(SR_CHANNEL_LOGIC)); - assert(snapshot); - const boost::shared_ptr logic_snapshot = boost::dynamic_pointer_cast(snapshot); - - if (!logic_snapshot || logic_snapshot->empty()) { - dialogs::DSMessageBox msg(this); - msg.mBox()->setText(tr("Search")); - msg.mBox()->setInformativeText(tr("No Sample data!")); - msg.mBox()->setStandardButtons(QMessageBox::Ok); - msg.mBox()->setIcon(QMessageBox::Warning); - msg.exec(); - return; - } - - const int64_t end = logic_snapshot->get_sample_count() - 1; - last_pos = _view.get_search_pos(); - last_hit = _view.get_search_hit(); - if (last_pos == 0) { - dialogs::DSMessageBox msg(this); - msg.mBox()->setText(tr("Search")); - msg.mBox()->setInformativeText(tr("Search cursor at the start position!")); - msg.mBox()->setStandardButtons(QMessageBox::Ok); - msg.mBox()->setIcon(QMessageBox::Warning); - msg.exec(); - return; - } else { - QFuture future; - future = QtConcurrent::run([&]{ - last_pos -= last_hit; - ret = logic_snapshot->pattern_search(0, end, false, last_pos, _pattern); - }); - Qt::WindowFlags flags = Qt::CustomizeWindowHint; - QProgressDialog dlg(tr("Search Previous..."), - tr("Cancel"),0,0,this,flags); - dlg.setWindowModality(Qt::WindowModal); - dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | - Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint); - dlg.setCancelButton(NULL); - - QFutureWatcher watcher; - connect(&watcher,SIGNAL(finished()),&dlg,SLOT(cancel())); - watcher.setFuture(future); - dlg.exec(); - - if (!ret) { - dialogs::DSMessageBox msg(this); - msg.mBox()->setText(tr("Search")); - msg.mBox()->setInformativeText(tr("Pattern not found!")); - msg.mBox()->setStandardButtons(QMessageBox::Ok); - msg.mBox()->setIcon(QMessageBox::Warning); - msg.exec(); - return; - } else { - _view.set_search_pos(last_pos, true); - } - } -} - -void SearchDock::on_next() -{ - bool ret; - int64_t last_pos; - const boost::shared_ptr snapshot(_session.get_snapshot(SR_CHANNEL_LOGIC)); - assert(snapshot); - const boost::shared_ptr logic_snapshot = boost::dynamic_pointer_cast(snapshot); - - if (!logic_snapshot || logic_snapshot->empty()) { - dialogs::DSMessageBox msg(this); - msg.mBox()->setText(tr("Search")); - msg.mBox()->setInformativeText(tr("No Sample data!")); - msg.mBox()->setStandardButtons(QMessageBox::Ok); - msg.mBox()->setIcon(QMessageBox::Warning); - msg.exec(); - return; - } - - const int64_t end = logic_snapshot->get_sample_count() - 1; - last_pos = _view.get_search_pos() + _view.get_search_hit(); - if (last_pos >= end) { - dialogs::DSMessageBox msg(this); - msg.mBox()->setText(tr("Search")); - msg.mBox()->setInformativeText(tr("Search cursor at the end position!")); - msg.mBox()->setStandardButtons(QMessageBox::Ok); - msg.mBox()->setIcon(QMessageBox::Warning); - msg.exec(); - return; - } else { - QFuture future; - future = QtConcurrent::run([&]{ - ret = logic_snapshot->pattern_search(0, end, true, last_pos, _pattern); - }); - Qt::WindowFlags flags = Qt::CustomizeWindowHint; - QProgressDialog dlg(tr("Search Next..."), - tr("Cancel"),0,0,this,flags); - dlg.setWindowModality(Qt::WindowModal); - dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | - Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint); - dlg.setCancelButton(NULL); - - QFutureWatcher watcher; - connect(&watcher,SIGNAL(finished()),&dlg,SLOT(cancel())); - watcher.setFuture(future); - dlg.exec(); - - if (!ret) { - dialogs::DSMessageBox msg(this); - msg.mBox()->setText(tr("Search")); - msg.mBox()->setInformativeText(tr("Pattern not found!")); - msg.mBox()->setStandardButtons(QMessageBox::Ok); - msg.mBox()->setIcon(QMessageBox::Warning); - msg.exec(); - return; - } else { - _view.set_search_pos(last_pos, true); - } - } -} - -void SearchDock::on_set() -{ - dialogs::Search dlg(this, _session, _pattern); - if (dlg.exec()) { - std::map new_pattern = dlg.get_pattern(); - - QString search_label; - for (auto& iter:new_pattern) { - iter.second.remove(QChar(' '), Qt::CaseInsensitive); - iter.second = iter.second.toUpper(); - search_label.push_back(iter.second); - } - - _search_value->setText(search_label); - QFontMetrics fm = this->fontMetrics(); - _search_value->setFixedWidth(fm.width(search_label)+_search_button->width()+20); - - if (new_pattern != _pattern) { - _view.set_search_pos(_view.get_search_pos(), false); - _pattern = new_pattern; - } - } -} - -} // namespace dock -} // namespace pv +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2013 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "searchdock.h" +#include "../sigsession.h" +#include "../view/cursor.h" +#include "../view/view.h" +#include "../view/timemarker.h" +#include "../view/ruler.h" +#include "../dialogs/search.h" +#include "../data/snapshot.h" +#include "../data/logicsnapshot.h" +#include "../device/devinst.h" +#include "../dialogs/dsmessagebox.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace pv { +namespace dock { + +using namespace pv::view; +using namespace pv::widgets; + +SearchDock::SearchDock(QWidget *parent, View &view, SigSession &session) : + QWidget(parent), + _session(session), + _view(view) +{ + connect(&_pre_button, SIGNAL(clicked()), + this, SLOT(on_previous())); + connect(&_nxt_button, SIGNAL(clicked()), + this, SLOT(on_next())); + + _search_button = new QPushButton(this); + _search_button->setFixedWidth(_search_button->height()); + _search_button->setDisabled(true); + + QLineEdit *_search_parent = new QLineEdit(this); + _search_parent->setVisible(false); + _search_value = new FakeLineEdit(_search_parent); + + QHBoxLayout *search_layout = new QHBoxLayout(); + search_layout->addWidget(_search_button); + search_layout->addStretch(); + search_layout->setContentsMargins(0, 0, 0, 0); + _search_value->setLayout(search_layout); + _search_value->setTextMargins(_search_button->width(), 0, 0, 0); + _search_value->setReadOnly(true); + + connect(_search_value, SIGNAL(trigger()), this, SLOT(on_set())); + + QHBoxLayout *layout = new QHBoxLayout(); + layout->addStretch(1); + layout->addWidget(&_pre_button); + layout->addWidget(_search_value); + layout->addWidget(&_nxt_button); + layout->addStretch(1); + + setLayout(layout); + + retranslateUi(); +} + +SearchDock::~SearchDock() +{ +} + +void SearchDock::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + retranslateUi(); + else if (event->type() == QEvent::StyleChange) + reStyle(); + QWidget::changeEvent(event); +} + +void SearchDock::retranslateUi() +{ + _search_value->setPlaceholderText(tr("search")); +} + +void SearchDock::reStyle() +{ + QString iconPath = ":/icons/" + qApp->property("Style").toString(); + + _pre_button.setIcon(QIcon(iconPath+"/pre.png")); + _nxt_button.setIcon(QIcon(iconPath+"/next.png")); + _search_button->setIcon(QIcon(iconPath+"/search.png")); +} + +void SearchDock::paintEvent(QPaintEvent *) +{ +// QStyleOption opt; +// opt.init(this); +// QPainter p(this); +// style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); +} + +void SearchDock::on_previous() +{ + bool ret; + int64_t last_pos; + bool last_hit; + const boost::shared_ptr snapshot(_session.get_snapshot(SR_CHANNEL_LOGIC)); + assert(snapshot); + const boost::shared_ptr logic_snapshot = boost::dynamic_pointer_cast(snapshot); + + if (!logic_snapshot || logic_snapshot->empty()) { + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Search")); + msg.mBox()->setInformativeText(tr("No Sample data!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); + msg.exec(); + return; + } + + const int64_t end = logic_snapshot->get_sample_count() - 1; + last_pos = _view.get_search_pos(); + last_hit = _view.get_search_hit(); + if (last_pos == 0) { + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Search")); + msg.mBox()->setInformativeText(tr("Search cursor at the start position!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); + msg.exec(); + return; + } else { + QFuture future; + future = QtConcurrent::run([&]{ + last_pos -= last_hit; + ret = logic_snapshot->pattern_search(0, end, false, last_pos, _pattern); + }); + Qt::WindowFlags flags = Qt::CustomizeWindowHint; + QProgressDialog dlg(tr("Search Previous..."), + tr("Cancel"),0,0,this,flags); + dlg.setWindowModality(Qt::WindowModal); + dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | + Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint); + dlg.setCancelButton(NULL); + + QFutureWatcher watcher; + connect(&watcher,SIGNAL(finished()),&dlg,SLOT(cancel())); + watcher.setFuture(future); + dlg.exec(); + + if (!ret) { + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Search")); + msg.mBox()->setInformativeText(tr("Pattern not found!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); + msg.exec(); + return; + } else { + _view.set_search_pos(last_pos, true); + } + } +} + +void SearchDock::on_next() +{ + bool ret; + int64_t last_pos; + const boost::shared_ptr snapshot(_session.get_snapshot(SR_CHANNEL_LOGIC)); + assert(snapshot); + const boost::shared_ptr logic_snapshot = boost::dynamic_pointer_cast(snapshot); + + if (!logic_snapshot || logic_snapshot->empty()) { + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Search")); + msg.mBox()->setInformativeText(tr("No Sample data!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); + msg.exec(); + return; + } + + const int64_t end = logic_snapshot->get_sample_count() - 1; + last_pos = _view.get_search_pos() + _view.get_search_hit(); + if (last_pos >= end) { + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Search")); + msg.mBox()->setInformativeText(tr("Search cursor at the end position!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); + msg.exec(); + return; + } else { + QFuture future; + future = QtConcurrent::run([&]{ + ret = logic_snapshot->pattern_search(0, end, true, last_pos, _pattern); + }); + Qt::WindowFlags flags = Qt::CustomizeWindowHint; + QProgressDialog dlg(tr("Search Next..."), + tr("Cancel"),0,0,this,flags); + dlg.setWindowModality(Qt::WindowModal); + dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | + Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint); + dlg.setCancelButton(NULL); + + QFutureWatcher watcher; + connect(&watcher,SIGNAL(finished()),&dlg,SLOT(cancel())); + watcher.setFuture(future); + dlg.exec(); + + if (!ret) { + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Search")); + msg.mBox()->setInformativeText(tr("Pattern not found!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); + msg.exec(); + return; + } else { + _view.set_search_pos(last_pos, true); + } + } +} + +void SearchDock::on_set() +{ + dialogs::Search dlg(this, _session, _pattern); + if (dlg.exec()) { + std::map new_pattern = dlg.get_pattern(); + + QString search_label; + for (auto& iter:new_pattern) { + iter.second.remove(QChar(' '), Qt::CaseInsensitive); + iter.second = iter.second.toUpper(); + search_label.push_back(iter.second); + } + + _search_value->setText(search_label); + QFontMetrics fm = this->fontMetrics(); + _search_value->setFixedWidth(fm.width(search_label)+_search_button->width()+20); + + if (new_pattern != _pattern) { + _view.set_search_pos(_view.get_search_pos(), false); + _pattern = new_pattern; + } + } +} + +} // namespace dock +} // namespace pv diff --git a/DSView/pv/dock/searchdock.h b/DSView/pv/dock/searchdock.h old mode 100644 new mode 100755 index b328199a81f1bfa03b0c817a7c57dca645fb1aea..0f68daad98cbc13967a37baa41f2a5650162ff0b --- a/DSView/pv/dock/searchdock.h +++ b/DSView/pv/dock/searchdock.h @@ -1,90 +1,94 @@ -/* - * This file is part of the DSView project. - * DSView is based on PulseView. - * - * Copyright (C) 2013 DreamSourceLab - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#ifndef DSVIEW_PV_SEARCHDOCK_H -#define DSVIEW_PV_SEARCHDOCK_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include "../widgets/fakelineedit.h" - -namespace pv { - -class SigSession; - -namespace view { - class View; -} - -namespace widgets { - class FakeLineEdit; -} - -namespace dock { - -class SearchDock : public QWidget -{ - Q_OBJECT - -public: - SearchDock(QWidget *parent, pv::view::View &view, SigSession &session); - ~SearchDock(); - - void paintEvent(QPaintEvent *); - -public slots: - void on_previous(); - void on_next(); - void on_set(); - -private: - SigSession &_session; - view::View &_view; - std::map _pattern; - - QPushButton _pre_button; - QPushButton _nxt_button; - widgets::FakeLineEdit* _search_value; - QPushButton *_search_button; -}; - -} // namespace dock -} // namespace pv - -#endif // DSVIEW_PV_SEARCHDOCK_H +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2013 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef DSVIEW_PV_SEARCHDOCK_H +#define DSVIEW_PV_SEARCHDOCK_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "../widgets/fakelineedit.h" + +namespace pv { + +class SigSession; + +namespace view { + class View; +} + +namespace widgets { + class FakeLineEdit; +} + +namespace dock { + +class SearchDock : public QWidget +{ + Q_OBJECT + +public: + SearchDock(QWidget *parent, pv::view::View &view, SigSession &session); + ~SearchDock(); + + void paintEvent(QPaintEvent *); +private: + void changeEvent(QEvent *event); + void retranslateUi(); + void reStyle(); + +public slots: + void on_previous(); + void on_next(); + void on_set(); + +private: + SigSession &_session; + view::View &_view; + std::map _pattern; + + QPushButton _pre_button; + QPushButton _nxt_button; + widgets::FakeLineEdit* _search_value; + QPushButton *_search_button; +}; + +} // namespace dock +} // namespace pv + +#endif // DSVIEW_PV_SEARCHDOCK_H diff --git a/DSView/pv/dock/triggerdock.cpp b/DSView/pv/dock/triggerdock.cpp old mode 100644 new mode 100755 index 0e643669bc3b316f75f9ea781fd087e2966287e3..80c08d97f8c3728c04ee44708b40d2b477626bf4 --- a/DSView/pv/dock/triggerdock.cpp +++ b/DSView/pv/dock/triggerdock.cpp @@ -1,560 +1,618 @@ -/* - * This file is part of the DSView project. - * DSView is based on PulseView. - * - * Copyright (C) 2013 DreamSourceLab - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "triggerdock.h" -#include "../sigsession.h" -#include "../device/devinst.h" -#include "../dialogs/dsmessagebox.h" - -#include -#include -#include -#include -#include -#include - -#include "libsigrok4DSL/libsigrok.h" - -namespace pv { -namespace dock { - -const int TriggerDock::MinTrigPosition = 1; - -TriggerDock::TriggerDock(QWidget *parent, SigSession &session) : - QScrollArea(parent), - _session(session) -{ - int i; - - _widget = new QWidget(this); - - QFont font("Monaco"); - font.setStyleHint(QFont::Monospace); - font.setFixedPitch(true); - - simple_radioButton = new QRadioButton(tr("Simple Trigger"), _widget); - simple_radioButton->setChecked(true); - adv_radioButton = new QRadioButton(tr("Advanced Trigger"), _widget); - - position_label = new QLabel(tr("Trigger Position: "), _widget); - position_spinBox = new QSpinBox(_widget); - position_spinBox->setRange(MinTrigPosition, DS_MAX_TRIG_PERCENT); - position_spinBox->setButtonSymbols(QAbstractSpinBox::NoButtons); - position_slider = new QSlider(Qt::Horizontal, _widget); - position_slider->setRange(MinTrigPosition, DS_MAX_TRIG_PERCENT); - connect(position_slider, SIGNAL(valueChanged(int)), position_spinBox, SLOT(setValue(int))); - connect(position_spinBox, SIGNAL(valueChanged(int)), position_slider, SLOT(setValue(int))); - - stages_label = new QLabel(tr("Total Trigger Stages: "), _widget); - stages_label->setDisabled(true); - stages_comboBox = new QComboBox(_widget); - for (i = 1; i <= TriggerStages; i++) - stages_comboBox->addItem(QString::number(i)); - //stages_comboBox->setCurrentIndex(stages_comboBox->count() - 1); - stages_comboBox->setDisabled(true); - - stage_tabWidget = new QTabWidget(_widget); - stage_tabWidget->setTabPosition(QTabWidget::East); - //stage_tabWidget->setDisabled(true); - stage_tabWidget->setUsesScrollButtons(false); - - QRegExp value_rx("[10XRFCxrfc ]+"); - QValidator *value_validator = new QRegExpValidator(value_rx, _widget); - for (i = 0; i < TriggerStages; i++) { - QComboBox *_logic_comboBox = new QComboBox(_widget); - _logic_comboBox->addItem(tr("Or")); - _logic_comboBox->addItem(tr("And")); - _logic_comboBox->setCurrentIndex(1); - _logic_comboBox_list.push_back(_logic_comboBox); - - QLineEdit *_value0_lineEdit = new QLineEdit("X X X X X X X X X X X X X X X X", _widget); - _value0_lineEdit->setFont(font); - _value0_lineEdit->setValidator(value_validator); - _value0_lineEdit->setMaxLength(TriggerProbes * 2 - 1); - _value0_lineEdit->setInputMask("X X X X X X X X X X X X X X X X"); - _value0_lineEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - _value0_lineEdit_list.push_back(_value0_lineEdit); - QSpinBox *_count_spinBox = new QSpinBox(_widget); - _count_spinBox->setRange(1, INT32_MAX); - _count_spinBox->setButtonSymbols(QAbstractSpinBox::NoButtons); - _count_spinBox_list.push_back(_count_spinBox); - QComboBox *_inv0_comboBox = new QComboBox(_widget); - _inv0_comboBox->addItem(tr("==")); - _inv0_comboBox->addItem(tr("!=")); - _inv0_comboBox_list.push_back(_inv0_comboBox); - - QLineEdit *_value1_lineEdit = new QLineEdit("X X X X X X X X X X X X X X X X", _widget); - _value1_lineEdit->setFont(font); - _value1_lineEdit->setValidator(value_validator); - _value1_lineEdit->setMaxLength(TriggerProbes * 2 - 1); - _value1_lineEdit->setInputMask("X X X X X X X X X X X X X X X X"); - _value1_lineEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - _value1_lineEdit_list.push_back(_value1_lineEdit); - QComboBox *_inv1_comboBox = new QComboBox(_widget); - _inv1_comboBox->addItem(tr("==")); - _inv1_comboBox->addItem(tr("!=")); - _inv1_comboBox_list.push_back(_inv1_comboBox); - - QCheckBox *_contiguous_checkbox = new QCheckBox(_widget); - _contiguous_checkbox_list.push_back(_contiguous_checkbox); - - QLabel *value_exp_label = new QLabel("1 1 1 1 1 1\n5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 ", _widget); - QLabel *inv_exp_label = new QLabel(tr("Inv"), _widget); - QLabel *count_exp_label = new QLabel(tr("Counter"), _widget); - value_exp_label->setFont(font); - - QVBoxLayout *stage_layout = new QVBoxLayout(); - QGridLayout *stage_glayout = new QGridLayout(); - stage_glayout->setVerticalSpacing(5); - - stage_glayout->addWidget(value_exp_label, 1, 0); - stage_glayout->addWidget(inv_exp_label, 1, 1); - stage_glayout->addWidget(_value0_lineEdit, 2, 0); - stage_glayout->addWidget(_inv0_comboBox, 2, 1); - stage_glayout->addWidget(_logic_comboBox, 2, 2); - stage_glayout->addWidget(_value1_lineEdit, 3, 0); - stage_glayout->addWidget(_inv1_comboBox, 3, 1); - - stage_glayout->addWidget(new QLabel(_widget), 4, 0); - - stage_glayout->addWidget(new QLabel(tr("Contiguous")), 5, 1, 1, 2); - stage_glayout->addWidget(_contiguous_checkbox, 5, 0, 1, 1, Qt::AlignRight); - stage_glayout->addWidget(count_exp_label, 6, 1, 1, 2); - stage_glayout->addWidget(_count_spinBox, 6, 0); - - stage_layout->addLayout(stage_glayout); - stage_layout->addSpacing(20); - stage_layout->addWidget(new QLabel(tr("X: Don't care\n0: Low level\n1: High level\nR: Rising edge\nF: Falling edge\nC: Rising/Falling edge"))); - stage_layout->addStretch(1); - - QGroupBox *_stage_groupBox = new QGroupBox(tr("Stage")+QString::number(i), _widget); - _stage_groupBox->setFlat(true); - _stage_groupBox->setLayout(stage_layout); - _stage_groupBox_list.push_back(_stage_groupBox); - - stage_tabWidget->addTab((QWidget *)_stage_groupBox, QString::number(i)); - - connect(_value0_lineEdit, SIGNAL(editingFinished()), this, SLOT(value_changed())); - connect(_value1_lineEdit, SIGNAL(editingFinished()), this, SLOT(value_changed())); - } - - _serial_start_label = new QLabel(tr("Start Flag: "), _widget); - _serial_start_lineEdit = new QLineEdit("X X X X X X X X X X X X X X X X", _widget); - _serial_start_lineEdit->setFont(font); - _serial_start_lineEdit->setValidator(value_validator); - _serial_start_lineEdit->setMaxLength(TriggerProbes * 2 - 1); - _serial_start_lineEdit->setInputMask("X X X X X X X X X X X X X X X X"); - _serial_start_lineEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - - _serial_stop_label = new QLabel(tr("Stop Flag: "), _widget); - _serial_stop_lineEdit = new QLineEdit("X X X X X X X X X X X X X X X X", _widget); - _serial_stop_lineEdit->setFont(font); - _serial_stop_lineEdit->setValidator(value_validator); - _serial_stop_lineEdit->setMaxLength(TriggerProbes * 2 - 1); - _serial_stop_lineEdit->setInputMask("X X X X X X X X X X X X X X X X"); - _serial_stop_lineEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - - _serial_edge_label = new QLabel(tr("Clock Flag: "), _widget); - _serial_edge_lineEdit = new QLineEdit("X X X X X X X X X X X X X X X X", _widget); - _serial_edge_lineEdit->setFont(font); - _serial_edge_lineEdit->setValidator(value_validator); - _serial_edge_lineEdit->setMaxLength(TriggerProbes * 2 - 1); - _serial_edge_lineEdit->setInputMask("X X X X X X X X X X X X X X X X"); - _serial_edge_lineEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - - _serial_data_lable = new QLabel(tr("Data Channel: "), _widget); - _serial_data_comboBox = new QComboBox(_widget); - for(i = 0; i < TriggerProbes; i++) - _serial_data_comboBox->addItem(QString::number(i)); - - _serial_value_lable = new QLabel(tr("Data Value: "), _widget); - _serial_value_lineEdit = new QLineEdit("X X X X X X X X X X X X X X X X", _widget); - _serial_value_lineEdit->setFont(font); - _serial_value_lineEdit->setValidator(value_validator); - _serial_value_lineEdit->setMaxLength(TriggerProbes * 2 - 1); - _serial_value_lineEdit->setInputMask("X X X X X X X X X X X X X X X X"); - _serial_value_lineEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - - _serial_bits_comboBox = new QComboBox(_widget); - for(i = 1; i <= 16; i++) - _serial_bits_comboBox->addItem(QString::number(i)); - - QLabel *serial_value_exp_label = new QLabel("1 1 1 1 1 1\n5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0", _widget); - serial_value_exp_label->setFont(font); - - QVBoxLayout *serial_layout = new QVBoxLayout(); - QGridLayout *serial_glayout = new QGridLayout(); - serial_glayout->setVerticalSpacing(5); - serial_glayout->addWidget(serial_value_exp_label, 1, 1, 1, 3); - serial_glayout->addWidget(_serial_start_label, 2, 0); - serial_glayout->addWidget(_serial_start_lineEdit, 2, 1, 1, 3); - serial_glayout->addWidget(new QLabel(_widget), 2, 4); - serial_glayout->addWidget(_serial_stop_label, 3, 0); - serial_glayout->addWidget(_serial_stop_lineEdit, 3, 1, 1, 3); - serial_glayout->addWidget(_serial_edge_label, 4, 0); - serial_glayout->addWidget(_serial_edge_lineEdit, 4, 1, 1, 3); - - serial_glayout->addWidget(new QLabel(_widget), 5, 0, 1, 5); - serial_glayout->addWidget(_serial_data_lable, 6, 0); - serial_glayout->addWidget(_serial_data_comboBox, 6, 1); - serial_glayout->addWidget(new QLabel(tr("Data Bits"), _widget), 7, 0); - serial_glayout->addWidget(_serial_bits_comboBox, 7, 1); - serial_glayout->addWidget(_serial_value_lable, 8, 0); - serial_glayout->addWidget(_serial_value_lineEdit, 8, 1, 1, 3); - - serial_layout->addLayout(serial_glayout); - serial_layout->addSpacing(20); - serial_layout->addWidget(new QLabel(tr("X: Don't care\n0: Low level\n1: High level\nR: Rising edge\nF: Falling edge\nC: Rising/Falling edge"))); - serial_layout->addStretch(1); - - _serial_groupBox = new QGroupBox(tr("Serial Trigger"), _widget); - _serial_groupBox->setFlat(true); - _serial_groupBox->setLayout(serial_layout); - //_serial_groupBox->setDisabled(true); - - connect(_serial_start_lineEdit, SIGNAL(editingFinished()), this, SLOT(value_changed())); - connect(_serial_stop_lineEdit, SIGNAL(editingFinished()), this, SLOT(value_changed())); - connect(_serial_edge_lineEdit, SIGNAL(editingFinished()), this, SLOT(value_changed())); - connect(_serial_value_lineEdit, SIGNAL(editingFinished()), this, SLOT(value_changed())); - - - _adv_tabWidget = new QTabWidget(_widget); - _adv_tabWidget->setTabPosition(QTabWidget::North); - _adv_tabWidget->setDisabled(true); - _adv_tabWidget->addTab((QWidget *)stage_tabWidget, tr("Stage Trigger")); - _adv_tabWidget->addTab((QWidget *)_serial_groupBox, tr("Serial Trigger")); - - connect(simple_radioButton, SIGNAL(clicked()), this, SLOT(simple_trigger())); - connect(adv_radioButton, SIGNAL(clicked()), this, SLOT(adv_trigger())); - connect(stages_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(widget_enable(int))); - - - QVBoxLayout *layout = new QVBoxLayout(_widget); - QGridLayout *gLayout = new QGridLayout(); - gLayout->setVerticalSpacing(5); - gLayout->addWidget(simple_radioButton, 0, 0); - gLayout->addWidget(adv_radioButton, 1, 0); - gLayout->addWidget(position_label, 2, 0); - gLayout->addWidget(position_spinBox, 2, 1); - gLayout->addWidget(new QLabel(tr("%"), _widget), 2, 2); - gLayout->addWidget(position_slider, 3, 0, 1, 3); - gLayout->addWidget(stages_label, 4, 0); - gLayout->addWidget(stages_comboBox, 4, 1); - gLayout->addWidget(new QLabel(_widget), 4, 2); - gLayout->setColumnStretch(2, 1); - - layout->addLayout(gLayout); - layout->addWidget(_adv_tabWidget); - layout->addStretch(1); - _widget->setLayout(layout); - - this->setWidget(_widget); - //_widget->setGeometry(0, 0, sizeHint().width(), 1000); - _widget->setObjectName("triggerWidget"); -} - -TriggerDock::~TriggerDock() -{ -} - -void TriggerDock::paintEvent(QPaintEvent *) -{ -// QStyleOption opt; -// opt.init(this); -// QPainter p(this); -// style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); -} - -void TriggerDock::simple_trigger() -{ - stages_label->setDisabled(true); - stages_comboBox->setDisabled(true); - _adv_tabWidget->setDisabled(true); -} - -void TriggerDock::adv_trigger() -{ - if (_session.get_device()->name() == "DSLogic") { - bool stream = false; - GVariant *gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_STREAM); - if (gvar != NULL) { - stream = g_variant_get_boolean(gvar); - g_variant_unref(gvar); - } - if (stream) { - dialogs::DSMessageBox msg(this); - msg.mBox()->setText(tr("Trigger")); - msg.mBox()->setInformativeText(tr("Stream Mode Don't Support Advanced Trigger!")); - msg.mBox()->setStandardButtons(QMessageBox::Ok); - msg.mBox()->setIcon(QMessageBox::Warning); - msg.exec(); - simple_radioButton->setChecked(true); - } else { - widget_enable(0); - } - } else { - dialogs::DSMessageBox msg(this); - msg.mBox()->setText(tr("Trigger")); - msg.mBox()->setInformativeText(tr("Advanced Trigger need DSLogic Hardware Support!")); - msg.mBox()->setStandardButtons(QMessageBox::Ok); - msg.mBox()->setIcon(QMessageBox::Warning); - msg.exec(); - simple_radioButton->setChecked(true); - } -} - -void TriggerDock::widget_enable(int index) -{ - (void) index; - - int i; - int enable_stages; - stages_label->setDisabled(false); - stages_comboBox->setVisible(true); - stages_comboBox->setDisabled(false); - _adv_tabWidget->setDisabled(false); - enable_stages = stages_comboBox->currentText().toInt(); - for (i = 0; i < enable_stages; i++) { - stage_tabWidget->setTabEnabled(i, true); - } - for (i = enable_stages; i < TriggerStages; i++) { - stage_tabWidget->setTabEnabled(i, false); - } -} - -void TriggerDock::value_changed() -{ - QLineEdit* sc=dynamic_cast(sender()); - if(sc != NULL) - sc->setText(sc->text().toUpper()); -} - -void TriggerDock::device_updated() -{ - uint64_t hw_depth; - bool stream = false; - uint8_t maxRange; - uint64_t sample_limits; - GVariant *gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_HW_DEPTH); - if (gvar != NULL) { - hw_depth = g_variant_get_uint64(gvar); - g_variant_unref(gvar); - - if (_session.get_device()->dev_inst()->mode == LOGIC) { - - gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_STREAM); - if (gvar != NULL) { - stream = g_variant_get_boolean(gvar); - g_variant_unref(gvar); - } - - sample_limits = _session.get_device()->get_sample_limit(); - if (stream) - maxRange = 1; - else if (hw_depth >= sample_limits) - maxRange = DS_MAX_TRIG_PERCENT; - else - maxRange = ceil(hw_depth * DS_MAX_TRIG_PERCENT / sample_limits); - position_spinBox->setRange(MinTrigPosition, maxRange); - position_slider->setRange(MinTrigPosition, maxRange); - - if (_session.get_device()->name().contains("virtual") || - stream) { - simple_radioButton->setChecked(true); - simple_trigger(); - } - } - } -} - -bool TriggerDock::commit_trigger() -{ - // trigger position update - ds_trigger_set_pos(position_slider->value()); - - // trigger mode update - if (simple_radioButton->isChecked()) { - ds_trigger_set_mode(SIMPLE_TRIGGER); - return 0; - } else { - ds_trigger_set_en(true); - if (_adv_tabWidget->currentIndex() == 0) - ds_trigger_set_mode(ADV_TRIGGER); - else if (_adv_tabWidget->currentIndex() == 1) - ds_trigger_set_mode(SERIAL_TRIGGER); - - // trigger stage update - ds_trigger_set_stage(stages_comboBox->currentText().toInt() - 1); - - int i; - // trigger value update - if (_adv_tabWidget->currentIndex() == 0) { - for (i = 0; i < stages_comboBox->currentText().toInt(); i++) { - ds_trigger_stage_set_value(i, TriggerProbes, - _value0_lineEdit_list.at(i)->text().toLocal8Bit().data(), - _value1_lineEdit_list.at(i)->text().toLocal8Bit().data()); - } - } else if(_adv_tabWidget->currentIndex() == 1){ - ds_trigger_stage_set_value(0, TriggerProbes, - _serial_start_lineEdit->text().toLocal8Bit().data(), - _serial_stop_lineEdit->text().toLocal8Bit().data()); - ds_trigger_stage_set_value(1, TriggerProbes, - _serial_edge_lineEdit->text().toLocal8Bit().data(), - _value1_lineEdit_list.at(1)->text().toLocal8Bit().data()); - - //_serial_data_comboBox - const int data_channel = _serial_data_comboBox->currentText().toInt(); - char channel[31]; - for(i = 0; i < 31; i++){ - if (i == (30 - 2*data_channel)) - channel[i] = '0'; - else if (i%2 == 0) - channel[i] = 'X'; - else - channel[i] = ' '; - } - ds_trigger_stage_set_value(2, TriggerProbes, - channel, - _value1_lineEdit_list.at(2)->text().toLocal8Bit().data()); - ds_trigger_stage_set_value(STriggerDataStage, TriggerProbes, - _serial_value_lineEdit->text().toLocal8Bit().data(), - _value1_lineEdit_list.at(3)->text().toLocal8Bit().data()); - } - - // trigger logic update - for (i = 0; i < stages_comboBox->currentText().toInt(); i++) { - const char logic = (_contiguous_checkbox_list.at(i)->isChecked() << 1) + - _logic_comboBox_list.at(i)->currentIndex(); - ds_trigger_stage_set_logic(i, TriggerProbes, - logic); - } - - // trigger inv update - for (i = 0; i < stages_comboBox->currentText().toInt(); i++) { - ds_trigger_stage_set_inv(i, TriggerProbes, - _inv0_comboBox_list.at(i)->currentIndex(), - _inv1_comboBox_list.at(i)->currentIndex()); - } - - // trigger count update - if (_adv_tabWidget->currentIndex() == 0) { - for (i = 0; i < stages_comboBox->currentText().toInt(); i++) { - ds_trigger_stage_set_count(i, TriggerProbes, - _count_spinBox_list.at(i)->value(), - 0); - } - } else if(_adv_tabWidget->currentIndex() == 1){ - ds_trigger_stage_set_count(1, TriggerProbes, - 1, - 0); - ds_trigger_stage_set_count(3, TriggerProbes, - _serial_bits_comboBox->currentText().toInt() - 1, - 0); - } - return 1; - } -} - -void TriggerDock::init() -{ - // TRIGGERPOS - //uint16_t pos = ds_trigger_get_pos(); - //position_slider->setValue(pos); -} - -QJsonObject TriggerDock::get_session() -{ - QJsonObject trigSes; - trigSes["advTriggerMode"] = adv_radioButton->isChecked(); - trigSes["triggerPos"] = position_slider->value(); - trigSes["triggerStages"] = stages_comboBox->currentIndex(); - trigSes["triggerTab"] = _adv_tabWidget->currentIndex(); - - for (int i = 0; i < stages_comboBox->count(); i++) { - QString value0_str = "stageTriggerValue0" + QString::number(i); - QString inv0_str = "stageTriggerInv0" + QString::number(i); - QString value1_str = "stageTriggerValue1" + QString::number(i); - QString inv1_str = "stageTriggerInv1" + QString::number(i); - - QString logic_str = "stageTriggerLogic" + QString::number(i); - QString count_str = "stageTriggerCount" + QString::number(i); - QString conti_str = "stageTriggerContiguous" + QString::number(i); - - trigSes[value0_str] = _value0_lineEdit_list.at(i)->text(); - trigSes[value1_str] = _value1_lineEdit_list.at(i)->text(); - trigSes[inv0_str] = _inv0_comboBox_list.at(i)->currentIndex(); - trigSes[inv1_str] = _inv1_comboBox_list.at(i)->currentIndex(); - - trigSes[logic_str] = _logic_comboBox_list.at(i)->currentIndex(); - trigSes[count_str] = _count_spinBox_list.at(i)->value(); - trigSes[conti_str] = _contiguous_checkbox_list.at(i)->isChecked(); - } - - trigSes["serialTriggerStart"] = _serial_start_lineEdit->text(); - trigSes["serialTriggerStop"] = _serial_stop_lineEdit->text(); - trigSes["serialTriggerClock"] = _serial_edge_lineEdit->text(); - trigSes["serialTriggerChannel"] = _serial_data_comboBox->currentIndex(); - trigSes["serialTriggerData"] = _serial_value_lineEdit->text(); - trigSes["serialTriggerBits"] = _serial_bits_comboBox->currentIndex(); - - return trigSes; -} - -void TriggerDock::set_session(QJsonObject ses) -{ - position_slider->setValue(ses["triggerPos"].toDouble()); - stages_comboBox->setCurrentIndex(ses["triggerStages"].toDouble()); - _adv_tabWidget->setCurrentIndex(ses["triggerTab"].toDouble()); - if (ses["advTriggerMode"].toBool()) - adv_radioButton->click(); - else - simple_radioButton->click(); - - for (int i = 0; i < stages_comboBox->count(); i++) { - QString value0_str = "stageTriggerValue0" + QString::number(i); - QString inv0_str = "stageTriggerInv0" + QString::number(i); - QString value1_str = "stageTriggerValue1" + QString::number(i); - QString inv1_str = "stageTriggerInv1" + QString::number(i); - - QString logic_str = "stageTriggerLogic" + QString::number(i); - QString count_str = "stageTriggerCount" + QString::number(i); - QString conti_str = "stageTriggerContiguous" + QString::number(i); - - _value0_lineEdit_list.at(i)->setText(ses[value0_str].toString()); - _value1_lineEdit_list.at(i)->setText(ses[value1_str].toString()); - _inv0_comboBox_list.at(i)->setCurrentIndex(ses[inv0_str].toDouble()); - _inv1_comboBox_list.at(i)->setCurrentIndex(ses[inv1_str].toDouble()); - - _logic_comboBox_list.at(i)->setCurrentIndex(ses[logic_str].toDouble()); - _count_spinBox_list.at(i)->setValue(ses[count_str].toDouble()); - _contiguous_checkbox_list.at(i)->setChecked(ses[conti_str].toBool()); - } - - _serial_start_lineEdit->setText(ses["serialTriggerStart"].toString()); - _serial_stop_lineEdit->setText(ses["serialTriggerStop"].toString()); - _serial_edge_lineEdit->setText(ses["serialTriggerClock"].toString()); - _serial_data_comboBox->setCurrentIndex(ses["serialTriggerChannel"].toDouble()); - _serial_value_lineEdit->setText(ses["serialTriggerData"].toString()); - _serial_bits_comboBox->setCurrentIndex(ses["serialTriggerBits"].toDouble()); -} - -} // namespace dock -} // namespace pv +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2013 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "triggerdock.h" +#include "../sigsession.h" +#include "../device/devinst.h" +#include "../dialogs/dsmessagebox.h" + +#include +#include +#include +#include +#include +#include + +#include "libsigrok4DSL/libsigrok.h" + +namespace pv { +namespace dock { + +const int TriggerDock::MinTrigPosition = 1; + +TriggerDock::TriggerDock(QWidget *parent, SigSession &session) : + QScrollArea(parent), + _session(session) +{ + int i; + + _widget = new QWidget(this); + + QFont font("Monaco"); + font.setStyleHint(QFont::Monospace); + font.setFixedPitch(true); + + _simple_radioButton = new QRadioButton(_widget); + _simple_radioButton->setChecked(true); + _adv_radioButton = new QRadioButton(_widget); + + _position_label = new QLabel(_widget); + _position_spinBox = new QSpinBox(_widget); + _position_spinBox->setRange(MinTrigPosition, DS_MAX_TRIG_PERCENT); + _position_spinBox->setButtonSymbols(QAbstractSpinBox::NoButtons); + _position_slider = new QSlider(Qt::Horizontal, _widget); + _position_slider->setRange(MinTrigPosition, DS_MAX_TRIG_PERCENT); + connect(_position_slider, SIGNAL(valueChanged(int)), _position_spinBox, SLOT(setValue(int))); + connect(_position_spinBox, SIGNAL(valueChanged(int)), _position_slider, SLOT(setValue(int))); + + _stages_label = new QLabel(_widget); + _stages_label->setDisabled(true); + stages_comboBox = new QComboBox(_widget); + for (i = 1; i <= TriggerStages; i++) + stages_comboBox->addItem(QString::number(i)); + //stages_comboBox->setCurrentIndex(stages_comboBox->count() - 1); + stages_comboBox->setDisabled(true); + + _stage_tabWidget = new QTabWidget(_widget); + _stage_tabWidget->setTabPosition(QTabWidget::East); + //_stage_tabWidget->setDisabled(true); + _stage_tabWidget->setUsesScrollButtons(false); + + QRegExp value_rx("[10XRFCxrfc ]+"); + QValidator *value_validator = new QRegExpValidator(value_rx, _widget); + for (i = 0; i < TriggerStages; i++) { + QComboBox *_logic_comboBox = new QComboBox(_widget); + _logic_comboBox->addItem(tr("Or")); + _logic_comboBox->addItem(tr("And")); + _logic_comboBox->setCurrentIndex(1); + _logic_comboBox_list.push_back(_logic_comboBox); + + QLineEdit *_value0_lineEdit = new QLineEdit("X X X X X X X X X X X X X X X X", _widget); + _value0_lineEdit->setFont(font); + _value0_lineEdit->setValidator(value_validator); + _value0_lineEdit->setMaxLength(TriggerProbes * 2 - 1); + _value0_lineEdit->setInputMask("X X X X X X X X X X X X X X X X"); + _value0_lineEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + _value0_lineEdit_list.push_back(_value0_lineEdit); + QSpinBox *_count_spinBox = new QSpinBox(_widget); + _count_spinBox->setRange(1, INT32_MAX); + _count_spinBox->setButtonSymbols(QAbstractSpinBox::NoButtons); + _count_spinBox_list.push_back(_count_spinBox); + QComboBox *_inv0_comboBox = new QComboBox(_widget); + _inv0_comboBox->addItem(tr("==")); + _inv0_comboBox->addItem(tr("!=")); + _inv0_comboBox_list.push_back(_inv0_comboBox); + + QLineEdit *_value1_lineEdit = new QLineEdit("X X X X X X X X X X X X X X X X", _widget); + _value1_lineEdit->setFont(font); + _value1_lineEdit->setValidator(value_validator); + _value1_lineEdit->setMaxLength(TriggerProbes * 2 - 1); + _value1_lineEdit->setInputMask("X X X X X X X X X X X X X X X X"); + _value1_lineEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + _value1_lineEdit_list.push_back(_value1_lineEdit); + QComboBox *_inv1_comboBox = new QComboBox(_widget); + _inv1_comboBox->addItem(tr("==")); + _inv1_comboBox->addItem(tr("!=")); + _inv1_comboBox_list.push_back(_inv1_comboBox); + + QCheckBox *_contiguous_checkbox = new QCheckBox(_widget); + _contiguous_checkbox_list.push_back(_contiguous_checkbox); + + QLabel *value_exp_label = new QLabel("1 1 1 1 1 1\n5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 ", _widget); + QLabel *inv_exp_label = new QLabel(_widget); + _inv_exp_label_list.push_back(inv_exp_label); + QLabel *count_exp_label = new QLabel(_widget); + _count_exp_label_list.push_back(count_exp_label); + value_exp_label->setFont(font); + + QVBoxLayout *stage_layout = new QVBoxLayout(); + QGridLayout *stage_glayout = new QGridLayout(); + stage_glayout->setVerticalSpacing(5); + + stage_glayout->addWidget(value_exp_label, 1, 0); + stage_glayout->addWidget(inv_exp_label, 1, 1); + stage_glayout->addWidget(_value0_lineEdit, 2, 0); + stage_glayout->addWidget(_inv0_comboBox, 2, 1); + stage_glayout->addWidget(_logic_comboBox, 2, 2); + stage_glayout->addWidget(_value1_lineEdit, 3, 0); + stage_glayout->addWidget(_inv1_comboBox, 3, 1); + + stage_glayout->addWidget(new QLabel(_widget), 4, 0); + + QLabel *contiguous_label = new QLabel(_widget); + _contiguous_label_list.push_back(contiguous_label); + stage_glayout->addWidget(contiguous_label, 5, 1, 1, 2); + stage_glayout->addWidget(_contiguous_checkbox, 5, 0, 1, 1, Qt::AlignRight); + stage_glayout->addWidget(count_exp_label, 6, 1, 1, 2); + stage_glayout->addWidget(_count_spinBox, 6, 0); + + stage_layout->addLayout(stage_glayout); + stage_layout->addSpacing(20); + QLabel *stage_note_label = new QLabel(_widget); + _stage_note_label_list.push_back(stage_note_label); + stage_layout->addWidget(stage_note_label); + stage_layout->addStretch(1); + + QGroupBox *stage_groupBox = new QGroupBox(_widget); + stage_groupBox->setFlat(true); + stage_groupBox->setLayout(stage_layout); + _stage_groupBox_list.push_back(stage_groupBox); + + _stage_tabWidget->addTab((QWidget *)stage_groupBox, QString::number(i)); + + connect(_value0_lineEdit, SIGNAL(editingFinished()), this, SLOT(value_changed())); + connect(_value1_lineEdit, SIGNAL(editingFinished()), this, SLOT(value_changed())); + } + + _serial_start_label = new QLabel(_widget); + _serial_start_lineEdit = new QLineEdit("X X X X X X X X X X X X X X X X", _widget); + _serial_start_lineEdit->setFont(font); + _serial_start_lineEdit->setValidator(value_validator); + _serial_start_lineEdit->setMaxLength(TriggerProbes * 2 - 1); + _serial_start_lineEdit->setInputMask("X X X X X X X X X X X X X X X X"); + _serial_start_lineEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + + _serial_stop_label = new QLabel(_widget); + _serial_stop_lineEdit = new QLineEdit("X X X X X X X X X X X X X X X X", _widget); + _serial_stop_lineEdit->setFont(font); + _serial_stop_lineEdit->setValidator(value_validator); + _serial_stop_lineEdit->setMaxLength(TriggerProbes * 2 - 1); + _serial_stop_lineEdit->setInputMask("X X X X X X X X X X X X X X X X"); + _serial_stop_lineEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + + _serial_edge_label = new QLabel(_widget); + _serial_edge_lineEdit = new QLineEdit("X X X X X X X X X X X X X X X X", _widget); + _serial_edge_lineEdit->setFont(font); + _serial_edge_lineEdit->setValidator(value_validator); + _serial_edge_lineEdit->setMaxLength(TriggerProbes * 2 - 1); + _serial_edge_lineEdit->setInputMask("X X X X X X X X X X X X X X X X"); + _serial_edge_lineEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + + _serial_data_label = new QLabel(_widget); + _serial_data_comboBox = new QComboBox(_widget); + for(i = 0; i < TriggerProbes; i++) + _serial_data_comboBox->addItem(QString::number(i)); + + _serial_value_label = new QLabel(_widget); + _serial_value_lineEdit = new QLineEdit("X X X X X X X X X X X X X X X X", _widget); + _serial_value_lineEdit->setFont(font); + _serial_value_lineEdit->setValidator(value_validator); + _serial_value_lineEdit->setMaxLength(TriggerProbes * 2 - 1); + _serial_value_lineEdit->setInputMask("X X X X X X X X X X X X X X X X"); + _serial_value_lineEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + + _serial_bits_comboBox = new QComboBox(_widget); + for(i = 1; i <= 16; i++) + _serial_bits_comboBox->addItem(QString::number(i)); + + QLabel *serial_value_exp_label = new QLabel("1 1 1 1 1 1\n5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0", _widget); + serial_value_exp_label->setFont(font); + + QVBoxLayout *serial_layout = new QVBoxLayout(); + QGridLayout *serial_glayout = new QGridLayout(); + serial_glayout->setVerticalSpacing(5); + serial_glayout->addWidget(serial_value_exp_label, 1, 1, 1, 3); + serial_glayout->addWidget(_serial_start_label, 2, 0); + serial_glayout->addWidget(_serial_start_lineEdit, 2, 1, 1, 3); + serial_glayout->addWidget(new QLabel(_widget), 2, 4); + serial_glayout->addWidget(_serial_stop_label, 3, 0); + serial_glayout->addWidget(_serial_stop_lineEdit, 3, 1, 1, 3); + serial_glayout->addWidget(_serial_edge_label, 4, 0); + serial_glayout->addWidget(_serial_edge_lineEdit, 4, 1, 1, 3); + + serial_glayout->addWidget(new QLabel(_widget), 5, 0, 1, 5); + serial_glayout->addWidget(_serial_data_label, 6, 0); + serial_glayout->addWidget(_serial_data_comboBox, 6, 1); + _data_bits_label = new QLabel(_widget); + serial_glayout->addWidget(_data_bits_label, 7, 0); + serial_glayout->addWidget(_serial_bits_comboBox, 7, 1); + serial_glayout->addWidget(_serial_value_label, 8, 0); + serial_glayout->addWidget(_serial_value_lineEdit, 8, 1, 1, 3); + + _serial_note_label = new QLabel(_widget); + serial_layout->addLayout(serial_glayout); + serial_layout->addSpacing(20); + serial_layout->addWidget(_serial_note_label); + serial_layout->addStretch(1); + + _serial_groupBox = new QGroupBox(_widget); + _serial_groupBox->setFlat(true); + _serial_groupBox->setLayout(serial_layout); + //_serial_groupBox->setDisabled(true); + + connect(_serial_start_lineEdit, SIGNAL(editingFinished()), this, SLOT(value_changed())); + connect(_serial_stop_lineEdit, SIGNAL(editingFinished()), this, SLOT(value_changed())); + connect(_serial_edge_lineEdit, SIGNAL(editingFinished()), this, SLOT(value_changed())); + connect(_serial_value_lineEdit, SIGNAL(editingFinished()), this, SLOT(value_changed())); + + + _adv_tabWidget = new QTabWidget(_widget); + _adv_tabWidget->setTabPosition(QTabWidget::North); + _adv_tabWidget->setDisabled(true); + _adv_tabWidget->addTab((QWidget *)_stage_tabWidget, tr("Stage Trigger")); + _adv_tabWidget->addTab((QWidget *)_serial_groupBox, tr("Serial Trigger")); + + connect(_simple_radioButton, SIGNAL(clicked()), this, SLOT(simple_trigger())); + connect(_adv_radioButton, SIGNAL(clicked()), this, SLOT(adv_trigger())); + connect(stages_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(widget_enable(int))); + + + QVBoxLayout *layout = new QVBoxLayout(_widget); + QGridLayout *gLayout = new QGridLayout(); + gLayout->setVerticalSpacing(5); + gLayout->addWidget(_simple_radioButton, 0, 0); + gLayout->addWidget(_adv_radioButton, 1, 0); + gLayout->addWidget(_position_label, 2, 0); + gLayout->addWidget(_position_spinBox, 2, 1); + gLayout->addWidget(new QLabel(tr("%"), _widget), 2, 2); + gLayout->addWidget(_position_slider, 3, 0, 1, 3); + gLayout->addWidget(_stages_label, 4, 0); + gLayout->addWidget(stages_comboBox, 4, 1); + gLayout->addWidget(new QLabel(_widget), 4, 2); + gLayout->setColumnStretch(2, 1); + + layout->addLayout(gLayout); + layout->addWidget(_adv_tabWidget); + layout->addStretch(1); + _widget->setLayout(layout); + + this->setWidget(_widget); + //_widget->setGeometry(0, 0, sizeHint().width(), 1000); + _widget->setObjectName("triggerWidget"); + + retranslateUi(); +} + +TriggerDock::~TriggerDock() +{ +} + +void TriggerDock::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + retranslateUi(); + else if (event->type() == QEvent::StyleChange) + reStyle(); + QScrollArea::changeEvent(event); +} + +void TriggerDock::retranslateUi() +{ + _simple_radioButton->setText(tr("Simple Trigger")); + _adv_radioButton->setText(tr("Advanced Trigger")); + _position_label->setText(tr("Trigger Position: ")); + _stages_label->setText(tr("Total Trigger Stages: ")); + _serial_start_label->setText(tr("Start Flag: ")); + _serial_stop_label->setText(tr("Stop Flag: ")); + _serial_edge_label->setText(tr("Clock Flag: ")); + _serial_data_label->setText(tr("Data Channel: ")); + _serial_value_label->setText(tr("Data Value: ")); + _serial_groupBox->setTitle(tr("Serial Trigger")); + + _adv_tabWidget->setTabText(0, tr("Stage Trigger")); + _adv_tabWidget->setTabText(1, tr("Serial Trigger")); + _serial_note_label->setText(tr("X: Don't care\n0: Low level\n1: High level\nR: Rising edge\nF: Falling edge\nC: Rising/Falling edge")); + _data_bits_label->setText(tr("Data Bits")); + + for (int i = 0; i < _inv_exp_label_list.length(); i++) + _inv_exp_label_list.at(i)->setText(tr("Inv")); + + for (int i = 0; i < _count_exp_label_list.length(); i++) + _count_exp_label_list.at(i)->setText(tr("Counter")); + + for (int i = 0; i < _contiguous_label_list.length(); i++) + _contiguous_label_list.at(i)->setText(tr("Contiguous")); + + for (int i = 0; i < _stage_groupBox_list.length(); i++) + _stage_groupBox_list.at(i)->setTitle(tr("Stage")+QString::number(i)); + + for (int i = 0; i < _stage_note_label_list.length(); i++) + _stage_note_label_list.at(i)->setText(tr("X: Don't care\n0: Low level\n1: High level\nR: Rising edge\nF: Falling edge\nC: Rising/Falling edge")); +} + +void TriggerDock::reStyle() +{ + //QString iconPath = ":/icons/" + qApp->property("Style").toString(); +} + +void TriggerDock::paintEvent(QPaintEvent *) +{ +// QStyleOption opt; +// opt.init(this); +// QPainter p(this); +// style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); +} + +void TriggerDock::simple_trigger() +{ + _stages_label->setDisabled(true); + stages_comboBox->setDisabled(true); + _adv_tabWidget->setDisabled(true); +} + +void TriggerDock::adv_trigger() +{ + if (_session.get_device()->name() == "DSLogic") { + bool stream = false; + GVariant *gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_STREAM); + if (gvar != NULL) { + stream = g_variant_get_boolean(gvar); + g_variant_unref(gvar); + } + if (stream) { + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Trigger")); + msg.mBox()->setInformativeText(tr("Stream Mode Don't Support Advanced Trigger!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); + msg.exec(); + _simple_radioButton->setChecked(true); + } else { + widget_enable(0); + } + } else { + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Trigger")); + msg.mBox()->setInformativeText(tr("Advanced Trigger need DSLogic Hardware Support!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); + msg.exec(); + _simple_radioButton->setChecked(true); + } +} + +void TriggerDock::widget_enable(int index) +{ + (void) index; + + int i; + int enable_stages; + _stages_label->setDisabled(false); + stages_comboBox->setVisible(true); + stages_comboBox->setDisabled(false); + _adv_tabWidget->setDisabled(false); + enable_stages = stages_comboBox->currentText().toInt(); + for (i = 0; i < enable_stages; i++) { + _stage_tabWidget->setTabEnabled(i, true); + } + for (i = enable_stages; i < TriggerStages; i++) { + _stage_tabWidget->setTabEnabled(i, false); + } +} + +void TriggerDock::value_changed() +{ + QLineEdit* sc=dynamic_cast(sender()); + if(sc != NULL) + sc->setText(sc->text().toUpper()); +} + +void TriggerDock::device_updated() +{ + uint64_t hw_depth; + bool stream = false; + uint8_t maxRange; + uint64_t sample_limits; + GVariant *gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_HW_DEPTH); + if (gvar != NULL) { + hw_depth = g_variant_get_uint64(gvar); + g_variant_unref(gvar); + + if (_session.get_device()->dev_inst()->mode == LOGIC) { + + gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_STREAM); + if (gvar != NULL) { + stream = g_variant_get_boolean(gvar); + g_variant_unref(gvar); + } + + sample_limits = _session.get_device()->get_sample_limit(); + if (stream) + maxRange = 1; + else if (hw_depth >= sample_limits) + maxRange = DS_MAX_TRIG_PERCENT; + else + maxRange = ceil(hw_depth * DS_MAX_TRIG_PERCENT / sample_limits); + _position_spinBox->setRange(MinTrigPosition, maxRange); + _position_slider->setRange(MinTrigPosition, maxRange); + + if (_session.get_device()->name().contains("virtual") || + stream) { + _simple_radioButton->setChecked(true); + simple_trigger(); + } + } + } +} + +bool TriggerDock::commit_trigger() +{ + // trigger position update + ds_trigger_set_pos(_position_slider->value()); + + // trigger mode update + if (_simple_radioButton->isChecked()) { + ds_trigger_set_mode(SIMPLE_TRIGGER); + return 0; + } else { + ds_trigger_set_en(true); + if (_adv_tabWidget->currentIndex() == 0) + ds_trigger_set_mode(ADV_TRIGGER); + else if (_adv_tabWidget->currentIndex() == 1) + ds_trigger_set_mode(SERIAL_TRIGGER); + + // trigger stage update + ds_trigger_set_stage(stages_comboBox->currentText().toInt() - 1); + + int i; + // trigger value update + if (_adv_tabWidget->currentIndex() == 0) { + for (i = 0; i < stages_comboBox->currentText().toInt(); i++) { + ds_trigger_stage_set_value(i, TriggerProbes, + _value0_lineEdit_list.at(i)->text().toLocal8Bit().data(), + _value1_lineEdit_list.at(i)->text().toLocal8Bit().data()); + } + } else if(_adv_tabWidget->currentIndex() == 1){ + ds_trigger_stage_set_value(0, TriggerProbes, + _serial_start_lineEdit->text().toLocal8Bit().data(), + _serial_stop_lineEdit->text().toLocal8Bit().data()); + ds_trigger_stage_set_value(1, TriggerProbes, + _serial_edge_lineEdit->text().toLocal8Bit().data(), + _value1_lineEdit_list.at(1)->text().toLocal8Bit().data()); + + //_serial_data_comboBox + const int data_channel = _serial_data_comboBox->currentText().toInt(); + char channel[31]; + for(i = 0; i < 31; i++){ + if (i == (30 - 2*data_channel)) + channel[i] = '0'; + else if (i%2 == 0) + channel[i] = 'X'; + else + channel[i] = ' '; + } + ds_trigger_stage_set_value(2, TriggerProbes, + channel, + _value1_lineEdit_list.at(2)->text().toLocal8Bit().data()); + ds_trigger_stage_set_value(STriggerDataStage, TriggerProbes, + _serial_value_lineEdit->text().toLocal8Bit().data(), + _value1_lineEdit_list.at(3)->text().toLocal8Bit().data()); + } + + // trigger logic update + for (i = 0; i < stages_comboBox->currentText().toInt(); i++) { + const char logic = (_contiguous_checkbox_list.at(i)->isChecked() << 1) + + _logic_comboBox_list.at(i)->currentIndex(); + ds_trigger_stage_set_logic(i, TriggerProbes, + logic); + } + + // trigger inv update + for (i = 0; i < stages_comboBox->currentText().toInt(); i++) { + ds_trigger_stage_set_inv(i, TriggerProbes, + _inv0_comboBox_list.at(i)->currentIndex(), + _inv1_comboBox_list.at(i)->currentIndex()); + } + + // trigger count update + if (_adv_tabWidget->currentIndex() == 0) { + for (i = 0; i < stages_comboBox->currentText().toInt(); i++) { + ds_trigger_stage_set_count(i, TriggerProbes, + _count_spinBox_list.at(i)->value(), + 0); + } + } else if(_adv_tabWidget->currentIndex() == 1){ + ds_trigger_stage_set_count(1, TriggerProbes, + 1, + 0); + ds_trigger_stage_set_count(3, TriggerProbes, + _serial_bits_comboBox->currentText().toInt() - 1, + 0); + } + return 1; + } +} + +void TriggerDock::init() +{ + // TRIGGERPOS + //uint16_t pos = ds_trigger_get_pos(); + //_position_slider->setValue(pos); +} + +QJsonObject TriggerDock::get_session() +{ + QJsonObject trigSes; + trigSes["advTriggerMode"] = _adv_radioButton->isChecked(); + trigSes["triggerPos"] = _position_slider->value(); + trigSes["triggerStages"] = stages_comboBox->currentIndex(); + trigSes["triggerTab"] = _adv_tabWidget->currentIndex(); + + for (int i = 0; i < stages_comboBox->count(); i++) { + QString value0_str = "stageTriggerValue0" + QString::number(i); + QString inv0_str = "stageTriggerInv0" + QString::number(i); + QString value1_str = "stageTriggerValue1" + QString::number(i); + QString inv1_str = "stageTriggerInv1" + QString::number(i); + + QString logic_str = "stageTriggerLogic" + QString::number(i); + QString count_str = "stageTriggerCount" + QString::number(i); + QString conti_str = "stageTriggerContiguous" + QString::number(i); + + trigSes[value0_str] = _value0_lineEdit_list.at(i)->text(); + trigSes[value1_str] = _value1_lineEdit_list.at(i)->text(); + trigSes[inv0_str] = _inv0_comboBox_list.at(i)->currentIndex(); + trigSes[inv1_str] = _inv1_comboBox_list.at(i)->currentIndex(); + + trigSes[logic_str] = _logic_comboBox_list.at(i)->currentIndex(); + trigSes[count_str] = _count_spinBox_list.at(i)->value(); + trigSes[conti_str] = _contiguous_checkbox_list.at(i)->isChecked(); + } + + trigSes["serialTriggerStart"] = _serial_start_lineEdit->text(); + trigSes["serialTriggerStop"] = _serial_stop_lineEdit->text(); + trigSes["serialTriggerClock"] = _serial_edge_lineEdit->text(); + trigSes["serialTriggerChannel"] = _serial_data_comboBox->currentIndex(); + trigSes["serialTriggerData"] = _serial_value_lineEdit->text(); + trigSes["serialTriggerBits"] = _serial_bits_comboBox->currentIndex(); + + return trigSes; +} + +void TriggerDock::set_session(QJsonObject ses) +{ + _position_slider->setValue(ses["triggerPos"].toDouble()); + stages_comboBox->setCurrentIndex(ses["triggerStages"].toDouble()); + _adv_tabWidget->setCurrentIndex(ses["triggerTab"].toDouble()); + if (ses["advTriggerMode"].toBool()) + _adv_radioButton->click(); + else + _simple_radioButton->click(); + + for (int i = 0; i < stages_comboBox->count(); i++) { + QString value0_str = "stageTriggerValue0" + QString::number(i); + QString inv0_str = "stageTriggerInv0" + QString::number(i); + QString value1_str = "stageTriggerValue1" + QString::number(i); + QString inv1_str = "stageTriggerInv1" + QString::number(i); + + QString logic_str = "stageTriggerLogic" + QString::number(i); + QString count_str = "stageTriggerCount" + QString::number(i); + QString conti_str = "stageTriggerContiguous" + QString::number(i); + + _value0_lineEdit_list.at(i)->setText(ses[value0_str].toString()); + _value1_lineEdit_list.at(i)->setText(ses[value1_str].toString()); + _inv0_comboBox_list.at(i)->setCurrentIndex(ses[inv0_str].toDouble()); + _inv1_comboBox_list.at(i)->setCurrentIndex(ses[inv1_str].toDouble()); + + _logic_comboBox_list.at(i)->setCurrentIndex(ses[logic_str].toDouble()); + _count_spinBox_list.at(i)->setValue(ses[count_str].toDouble()); + _contiguous_checkbox_list.at(i)->setChecked(ses[conti_str].toBool()); + } + + _serial_start_lineEdit->setText(ses["serialTriggerStart"].toString()); + _serial_stop_lineEdit->setText(ses["serialTriggerStop"].toString()); + _serial_edge_lineEdit->setText(ses["serialTriggerClock"].toString()); + _serial_data_comboBox->setCurrentIndex(ses["serialTriggerChannel"].toDouble()); + _serial_value_lineEdit->setText(ses["serialTriggerData"].toString()); + _serial_bits_comboBox->setCurrentIndex(ses["serialTriggerBits"].toDouble()); +} + +} // namespace dock +} // namespace pv diff --git a/DSView/pv/dock/triggerdock.h b/DSView/pv/dock/triggerdock.h old mode 100644 new mode 100755 index e63390c7c1f8a5e65696b91f500b04d540d3f041..d43389768f1cf0b5dd22a893e0f924446a3bc511 --- a/DSView/pv/dock/triggerdock.h +++ b/DSView/pv/dock/triggerdock.h @@ -1,136 +1,148 @@ -/* - * This file is part of the DSView project. - * DSView is based on PulseView. - * - * Copyright (C) 2013 DreamSourceLab - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#ifndef DSVIEW_PV_TRIGGERDOCK_H -#define DSVIEW_PV_TRIGGERDOCK_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -namespace pv { - -class SigSession; - -namespace dock { - -class TriggerDock : public QScrollArea -{ - Q_OBJECT - -private: - static const int MinTrigPosition; - -public: - TriggerDock(QWidget *parent, SigSession &session); - ~TriggerDock(); - - void paintEvent(QPaintEvent *); - - void init(); - - QJsonObject get_session(); - void set_session(QJsonObject ses); - - /* - * commit trigger setting - * return 0: simple trigger - * 1: advanced trigger - */ - bool commit_trigger(); - -signals: - -public slots: - void simple_trigger(); - void adv_trigger(); - void widget_enable(int index); - - void value_changed(); - - void device_updated(); - -private: - -private: - SigSession &_session; - - QWidget *_widget; - - QRadioButton *simple_radioButton; - QRadioButton *adv_radioButton; - - QLabel *position_label; - QSpinBox *position_spinBox; - QSlider *position_slider; - - QLabel *stages_label; - QComboBox *stages_comboBox; - - QTabWidget *stage_tabWidget; - - QVector _stage_groupBox_list; - QVector _mu_label_list; - QVector _logic_comboBox_list; - QVector _value0_lineEdit_list; - QVector _count_spinBox_list; - QVector _inv0_comboBox_list; - QVector _value1_lineEdit_list; - QVector _inv1_comboBox_list; - QVector _contiguous_checkbox_list; - - QTabWidget *_adv_tabWidget; - QGroupBox *_serial_groupBox; - QLabel *_serial_start_label; - QLineEdit *_serial_start_lineEdit; - QLabel *_serial_stop_label; - QLineEdit *_serial_stop_lineEdit; - QLabel *_serial_edge_label; - QLineEdit *_serial_edge_lineEdit; - QLabel *_serial_data_lable; - QComboBox *_serial_data_comboBox; - QLabel *_serial_value_lable; - QLineEdit *_serial_value_lineEdit; - QLabel *_serial_vcnt_lable; - QComboBox *_serial_bits_comboBox; -}; - -} // namespace dock -} // namespace pv - -#endif // DSVIEW_PV_TRIGGERDOCK_H +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2013 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef DSVIEW_PV_TRIGGERDOCK_H +#define DSVIEW_PV_TRIGGERDOCK_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +namespace pv { + +class SigSession; + +namespace dock { + +class TriggerDock : public QScrollArea +{ + Q_OBJECT + +private: + static const int MinTrigPosition; + +public: + TriggerDock(QWidget *parent, SigSession &session); + ~TriggerDock(); + + void paintEvent(QPaintEvent *); + + void init(); + + QJsonObject get_session(); + void set_session(QJsonObject ses); + + /* + * commit trigger setting + * return 0: simple trigger + * 1: advanced trigger + */ + bool commit_trigger(); +private: + void changeEvent(QEvent *event); + void retranslateUi(); + void reStyle(); + +signals: + +public slots: + void simple_trigger(); + void adv_trigger(); + void widget_enable(int index); + + void value_changed(); + + void device_updated(); + +private: + +private: + SigSession &_session; + + QWidget *_widget; + + QRadioButton *_simple_radioButton; + QRadioButton *_adv_radioButton; + + QLabel *_position_label; + QSpinBox *_position_spinBox; + QSlider *_position_slider; + + QLabel *_stages_label; + QComboBox *stages_comboBox; + + QTabWidget *_stage_tabWidget; + + QVector _stage_groupBox_list; + QVector _mu_label_list; + QVector _logic_comboBox_list; + QVector _value0_lineEdit_list; + QVector _count_spinBox_list; + QVector _inv0_comboBox_list; + QVector _value1_lineEdit_list; + QVector _inv1_comboBox_list; + QVector _contiguous_checkbox_list; + + QTabWidget *_adv_tabWidget; + QGroupBox *_serial_groupBox; + QLabel *_serial_start_label; + QLineEdit *_serial_start_lineEdit; + QLabel *_serial_stop_label; + QLineEdit *_serial_stop_lineEdit; + QLabel *_serial_edge_label; + QLineEdit *_serial_edge_lineEdit; + QLabel *_serial_data_label; + QComboBox *_serial_data_comboBox; + QLabel *_serial_value_label; + QLineEdit *_serial_value_lineEdit; + QComboBox *_serial_bits_comboBox; + + QLabel *_serial_note_label; + QLabel *_data_bits_label; + + QVector _inv_exp_label_list; + QVector _count_exp_label_list; + QVector _contiguous_label_list; + QVector _stage_note_label_list; + +}; + +} // namespace dock +} // namespace pv + +#endif // DSVIEW_PV_TRIGGERDOCK_H diff --git a/DSView/pv/mainframe.cpp b/DSView/pv/mainframe.cpp old mode 100644 new mode 100755 index eea4701ddf675c790dedc6b7d21dff6851129b87..804b751d52d7dd03b9ace69def829f329cbba153 --- a/DSView/pv/mainframe.cpp +++ b/DSView/pv/mainframe.cpp @@ -69,13 +69,14 @@ MainFrame::MainFrame(DeviceManager &device_manager, _freezing = false; _minimized = false; + // Title + _titleBar = new toolbars::TitleBar(true, this); + _titleBar->installEventFilter(this); + // MainWindow _mainWindow = new MainWindow(device_manager, open_file_name, this); _mainWindow->setWindowFlags(Qt::Widget); - // Title - _titleBar = new toolbars::TitleBar(true, this); - _titleBar->installEventFilter(this); _titleBar->setTitle(_mainWindow->windowTitle()); QVBoxLayout *vbox = new QVBoxLayout(); @@ -349,9 +350,11 @@ bool MainFrame::eventFilter(QObject *object, QEvent *event) void MainFrame::writeSettings() { - QSettings settings; + QSettings settings(QApplication::organizationName(), QApplication::applicationName()); settings.beginGroup("MainFrame"); + settings.setValue("style", qApp->property("Style").toString()); + settings.setValue("language", qApp->property("Language").toInt()); settings.setValue("isMax", isMaximized()); settings.setValue("size", size()); settings.setValue("pos", pos() + @@ -361,7 +364,7 @@ void MainFrame::writeSettings() void MainFrame::readSettings() { - QSettings settings; + QSettings settings(QApplication::organizationName(), QApplication::applicationName()); QDesktopWidget* desktopWidget = QApplication::desktop(); QRect deskRect = desktopWidget->availableGeometry(); QPoint default_upleft = QPoint((deskRect.width() - defWidth)/2, (deskRect.height() - defHeight)/2); @@ -371,6 +374,13 @@ void MainFrame::readSettings() bool isMax = settings.value("isMax", false).toBool(); QSize size = settings.value("size", default_size).toSize(); QPoint pos = settings.value("pos", default_upleft).toPoint(); + // defaut language + if (settings.contains("language")) { + _mainWindow->switchLanguage(settings.value("language").toInt()); + } else { + QLocale locale; + _mainWindow->switchLanguage(locale.language()); + } settings.endGroup(); // check the restored position is vavlid or not @@ -391,6 +401,9 @@ void MainFrame::readSettings() resize(size); move(pos); } + + // restore dockwidgets + _mainWindow->restore_dock(); } void MainFrame::setTaskbarProgress(int progress) @@ -401,14 +414,13 @@ void MainFrame::setTaskbarProgress(int progress) void MainFrame::show_doc() { const QString DOC_KEY("ShowDocuments"); - QSettings settings; - + QSettings settings(QApplication::organizationName(), QApplication::applicationName()); if (!settings.contains(DOC_KEY)) { dialogs::DSDialog dlg(this); dlg.setTitle(tr("Document")); QLabel tipsLabel; - tipsLabel.setPixmap(QPixmap(":/icons/showDoc.png")); + tipsLabel.setPixmap(QPixmap(":/icons/showDoc"+QString::number(_mainWindow->language())+".png")); QMessageBox msg; msg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint); msg.setContentsMargins(0, 0, 0, 0); @@ -426,10 +438,7 @@ void MainFrame::show_doc() dlg.exec(); if (msg.clickedButton() == openButton) { - QDir dir(DS_RES_PATH); - dir.cdUp(); - QDesktopServices::openUrl( - QUrl("file:///"+dir.absolutePath() + "/ug.pdf")); + _mainWindow->openDoc(); } if (msg.clickedButton() == noMoreButton) settings.setValue(DOC_KEY, false); diff --git a/DSView/pv/mainframe.h b/DSView/pv/mainframe.h old mode 100644 new mode 100755 index 9426e8a74dd3eee6fc87029d25798e1d2a79a3ae..0680946fe21cd2345ddb534e645cb85d3385fa4c --- a/DSView/pv/mainframe.h +++ b/DSView/pv/mainframe.h @@ -47,8 +47,8 @@ class MainFrame : public QFrame { Q_OBJECT public: - static const int minWidth = 600; - static const int minHeight = 500; + static const int minWidth = 800; + static const int minHeight = 600; static const int defWidth = 900; static const int defHeight = 680; diff --git a/DSView/pv/mainwindow.cpp b/DSView/pv/mainwindow.cpp old mode 100644 new mode 100755 index c66e9be099b05c921c0c125073a34b999e85a53d..80c1f8ec90fda5d5500135da7852c5f10385f2dd --- a/DSView/pv/mainwindow.cpp +++ b/DSView/pv/mainwindow.cpp @@ -59,6 +59,7 @@ #include "dialogs/storeprogress.h" #include "dialogs/waitingdialog.h" #include "dialogs/dsmessagebox.h" +#include "dialogs/regionoptions.h" #include "toolbars/samplingbar.h" #include "toolbars/trigbar.h" @@ -112,6 +113,7 @@ MainWindow::MainWindow(DeviceManager &device_manager, void MainWindow::setup_ui() { setObjectName(QString::fromUtf8("MainWindow")); + setContentsMargins(0,0,0,0); layout()->setMargin(0); layout()->setSpacing(0); @@ -124,9 +126,13 @@ void MainWindow::setup_ui() // Setup the sampling bar _sampling_bar = new toolbars::SamplingBar(_session, this); + _sampling_bar->setObjectName("sampling_bar"); _trig_bar = new toolbars::TrigBar(_session, this); + _trig_bar->setObjectName("trig_bar"); _file_bar = new toolbars::FileBar(_session, this); + _file_bar->setObjectName("file_bar"); _logo_bar = new toolbars::LogoBar(_session, this); + _logo_bar->setObjectName("logo_bar"); connect(_trig_bar, SIGNAL(on_protocol(bool)), this, SLOT(on_protocol(bool))); @@ -136,6 +142,8 @@ void MainWindow::setup_ui() SLOT(on_measure(bool))); connect(_trig_bar, SIGNAL(on_search(bool)), this, SLOT(on_search(bool))); + connect(_trig_bar, SIGNAL(setTheme(QString)), this, + SLOT(switchTheme(QString))); connect(_file_bar, SIGNAL(load_file(QString)), this, SLOT(load_file(QString))); connect(_file_bar, SIGNAL(on_save()), this, @@ -148,9 +156,14 @@ void MainWindow::setup_ui() SLOT(load_session(QString))); connect(_file_bar, SIGNAL(store_session(QString)), this, SLOT(store_session(QString))); + connect(_logo_bar, SIGNAL(setLanguage(int)), this, + SLOT(switchLanguage(int))); + connect(_logo_bar, SIGNAL(openDoc()), this, + SLOT(openDoc())); // trigger dock _trigger_dock=new QDockWidget(tr("Trigger Setting..."),this); + _trigger_dock->setObjectName("trigger_dock"); _trigger_dock->setFeatures(QDockWidget::DockWidgetMovable); _trigger_dock->setAllowedAreas(Qt::RightDockWidgetArea); _trigger_dock->setVisible(false); @@ -158,6 +171,7 @@ void MainWindow::setup_ui() _trigger_dock->setWidget(_trigger_widget); _dso_trigger_dock=new QDockWidget(tr("Trigger Setting..."),this); + _dso_trigger_dock->setObjectName("dso_trigger_dock"); _dso_trigger_dock->setFeatures(QDockWidget::DockWidgetMovable); _dso_trigger_dock->setAllowedAreas(Qt::RightDockWidgetArea); _dso_trigger_dock->setVisible(false); @@ -183,6 +197,8 @@ void MainWindow::setup_ui() SLOT(timebase_changed())); connect(_sampling_bar, SIGNAL(show_calibration()), _view, SLOT(show_calibration())); + connect(_trig_bar, SIGNAL(show_lissajous(bool)), _view, + SLOT(show_lissajous(bool))); connect(_dso_trigger_widget, SIGNAL(set_trig_pos(int)), _view, SLOT(set_trig_pos(int))); connect(_view, SIGNAL(auto_trig(int)), _dso_trigger_widget, @@ -198,6 +214,7 @@ void MainWindow::setup_ui() #ifdef ENABLE_DECODE // protocol dock _protocol_dock=new QDockWidget(tr("Protocol"),this); + _protocol_dock->setObjectName("protocol_dock"); _protocol_dock->setFeatures(QDockWidget::DockWidgetMovable); _protocol_dock->setAllowedAreas(Qt::RightDockWidgetArea); _protocol_dock->setVisible(false); @@ -210,6 +227,7 @@ void MainWindow::setup_ui() #endif // measure dock _measure_dock=new QDockWidget(tr("Measurement"),this); + _measure_dock->setObjectName("measure_dock"); _measure_dock->setFeatures(QDockWidget::DockWidgetMovable); _measure_dock->setAllowedAreas(Qt::RightDockWidgetArea); _measure_dock->setVisible(false); @@ -217,6 +235,7 @@ void MainWindow::setup_ui() _measure_dock->setWidget(_measure_widget); // search dock _search_dock=new QDockWidget(tr("Search..."), this); + _search_dock->setObjectName("search_dock"); _search_dock->setFeatures(QDockWidget::NoDockWidgetFeatures); _search_dock->setTitleBarWidget(new QWidget(_search_dock)); _search_dock->setAllowedAreas(Qt::BottomDockWidgetArea); @@ -265,8 +284,8 @@ void MainWindow::setup_ui() connect(_view, SIGNAL(cursor_moved()), _measure_widget, SLOT(reCalc())); connect(_view, SIGNAL(prgRate(int)), this, SIGNAL(prgRate(int))); - connect(_view, SIGNAL(update_device_list()), - this, SLOT(update_device_list()), Qt::DirectConnection); + connect(_view, SIGNAL(device_changed(bool)), + this, SLOT(device_changed(bool)), Qt::DirectConnection); // event filter _view->installEventFilter(this); @@ -285,9 +304,34 @@ void MainWindow::setup_ui() // Populate the device list and select the initially selected device _session.set_default_device(boost::bind(&MainWindow::session_error, this, QString(tr("Set Default Device failed")), _1)); + + // defaut language + QSettings settings(QApplication::organizationName(), QApplication::applicationName()); + QLocale locale; + settings.beginGroup("MainFrame"); + switchLanguage(settings.value("language", locale.language()).toInt()); + switchTheme(settings.value("style", "dark").toString()); + settings.endGroup(); + + // UI initial + _measure_widget->add_dist_measure(); + + // update device update_device_list(); _session.start_hotplug_proc(boost::bind(&MainWindow::session_error, this, QString(tr("Hotplug failed")), _1)); + + retranslateUi(); +} + + +void MainWindow::retranslateUi() +{ + _trigger_dock->setWindowTitle(tr("Trigger Setting...")); + _dso_trigger_dock->setWindowTitle(tr("Trigger Setting...")); + _protocol_dock->setWindowTitle(tr("Protocol")); + _measure_dock->setWindowTitle(tr("Measurement")); + _search_dock->setWindowTitle(tr("Search...")); } void MainWindow::session_error( @@ -302,6 +346,7 @@ void MainWindow::update_device_list() { assert(_sampling_bar); + switchLanguage(_language); _session.stop_capture(); _view->reload(); _trigger_widget->device_updated(); @@ -317,12 +362,6 @@ void MainWindow::update_device_list() shared_ptr file_dev; if((file_dev = dynamic_pointer_cast(selected_device))) { - #ifdef ENABLE_DECODE - // load decoders - StoreSession ss(_session); - ss.load_decoders(_protocol_widget, file_dev->get_decoders()); - #endif - // check version if (selected_device->dev_inst()->mode == LOGIC) { GVariant* gvar = selected_device->get_config(NULL, NULL, SR_CONF_FILE_VERSION); @@ -338,6 +377,15 @@ void MainWindow::update_device_list() } } + #ifdef ENABLE_DECODE + // load decoders + StoreSession ss(_session); + ss.load_decoders(_protocol_widget, file_dev->get_decoders()); + #endif + + // load session + load_session_json(file_dev->get_session(), true); + // load data const QString errorMessage( QString(tr("Failed to capture file data!"))); @@ -355,15 +403,31 @@ void MainWindow::update_device_list() #endif if (dir.exists()) { QString str = dir.absolutePath() + "/"; + QString lang_name = ".ses" + QString::number(_language); QString ses_name = str + selected_device->name() + QString::number(selected_device->dev_inst()->mode) + - ".dsc"; + lang_name + ".dsc"; load_session(ses_name); } } else { _file_bar->set_settings_en(false); _logo_bar->dsl_connected(false); + #ifdef Q_OS_LINUX + QDir dir(DS_RES_PATH); + #else + QDir dir(QCoreApplication::applicationDirPath()); + assert(dir.cd("res")); + #endif + if (dir.exists()) { + QString str = dir.absolutePath() + "/"; + QString ses_name = str + + selected_device->name() + + QString::number(selected_device->dev_inst()->mode) + + ".dsc"; + if (QFileInfo(ses_name).exists()) + load_session(ses_name); + } } _sampling_bar->reload(); _view->status_clear(); @@ -453,6 +517,16 @@ void MainWindow::device_detach() update_device_list(); } +void MainWindow::device_changed(bool close) +{ + if (close) { + _sampling_bar->set_sampling(false); + _session.set_default_device(boost::bind(&MainWindow::session_error, this, + QString(tr("Set Default Device failed")), _1)); + } + update_device_list(); +} + void MainWindow::run_stop() { switch(_session.get_capture_state()) { @@ -601,16 +675,23 @@ void MainWindow::session_save() dir.cd(path); QString driver_name = _session.get_device()->name(); QString mode_name = QString::number(_session.get_device()->dev_inst()->mode); - QString file_name = dir.absolutePath() + "/" + driver_name + mode_name + ".dsc"; + QString lang_name = ".ses" + QString::number(_language); + QString file_name = dir.absolutePath() + "/" + + driver_name + mode_name + + lang_name + ".dsc"; if (strncmp(driver_name.toLocal8Bit(), "virtual", 7) && !file_name.isEmpty()) { store_session(file_name); } } + + QSettings settings(QApplication::organizationName(), QApplication::applicationName()); + settings.setValue("windowState", saveState()); } void MainWindow::closeEvent(QCloseEvent *event) { + // not used, refer to closeEvent of mainFrame session_save(); event->accept(); } @@ -640,7 +721,7 @@ void MainWindow::commit_trigger(bool instant) { int i = 0; const QString TRIG_KEY("WarnofMultiTrig"); - QSettings settings; + QSettings settings(QApplication::organizationName(), QApplication::applicationName()); ds_trigger_init(); @@ -703,7 +784,7 @@ void MainWindow::on_search(bool visible) void MainWindow::on_screenShot() { const QString DIR_KEY("ScreenShotPath"); - QSettings settings; + QSettings settings(QApplication::organizationName(), QApplication::applicationName()); QPixmap pixmap; QDesktopWidget *desktop = QApplication::desktop(); pixmap = QPixmap::grabWindow(desktop->winId(), parentWidget()->pos().x(), parentWidget()->pos().y(), @@ -724,13 +805,35 @@ void MainWindow::on_screenShot() void MainWindow::on_save() { using pv::dialogs::StoreProgress; + +// dialogs::RegionOptions *regionDlg = new dialogs::RegionOptions(_view, _session, this); +// regionDlg->exec(); + + QString session_file; + QDir dir; + #if QT_VERSION >= 0x050400 + QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + #else + QString path = QStandardPaths::writableLocation(QStandardPaths::DataLocation); + #endif + if(dir.mkpath(path)) { + dir.cd(path); + + session_file = dir.absolutePath() + "/DSView-session-XXXXXX"; + store_session(session_file); + } + StoreProgress *dlg = new StoreProgress(_session, this); - dlg->save_run(); + dlg->save_run(session_file); } void MainWindow::on_export() { using pv::dialogs::StoreProgress; + +// dialogs::RegionOptions *regionDlg = new dialogs::RegionOptions(_view, _session, this); +// regionDlg->exec(); + StoreProgress *dlg = new StoreProgress(_session, this); dlg->export_run(); } @@ -745,7 +848,13 @@ bool MainWindow::load_session(QString name) QString sessionData = QString::fromUtf8(sessionFile.readAll()); QJsonDocument sessionDoc = QJsonDocument::fromJson(sessionData.toUtf8()); - QJsonObject sessionObj = sessionDoc.object(); + + return load_session_json(sessionDoc, false); +} + +bool MainWindow::load_session_json(QJsonDocument json, bool file_dev) +{ + QJsonObject sessionObj = json.object(); // check session file version if (!sessionObj.contains("Version") || @@ -754,7 +863,7 @@ bool MainWindow::load_session(QString name) // check device and mode const sr_dev_inst *const sdi = _session.get_device()->dev_inst(); - if (strcmp(sdi->driver->name, sessionObj["Device"].toString().toLocal8Bit()) != 0 || + if ((!file_dev && strcmp(sdi->driver->name, sessionObj["Device"].toString().toLocal8Bit()) != 0) || sdi->mode != sessionObj["DeviceMode"].toDouble()) { dialogs::DSMessageBox msg(this); msg.mBox()->setText(tr("Session Error")); @@ -765,6 +874,20 @@ bool MainWindow::load_session(QString name) return false; } + // check language + if (sessionObj.contains("Language")) { + switchLanguage(sessionObj["Language"].toInt()); + } else { + bool language_matched = _session.get_device()->set_config(NULL, NULL, SR_CONF_OPERATION_MODE, + g_variant_new_string(sessionObj["Operation Mode"].toString().toUtf8())); + if (!language_matched) { + if (_language != QLocale::Chinese) + switchLanguage(QLocale::Chinese); + else + switchLanguage(QLocale::English); + } + } + // clear decoders #ifdef ENABLE_DECODE if (sdi->mode == LOGIC) { @@ -842,14 +965,14 @@ bool MainWindow::load_session(QString name) boost::shared_ptr dsoSig; if ((dsoSig = dynamic_pointer_cast(s))) { dsoSig->load_settings(); - dsoSig->set_zero_vrate(obj["zeroPos"].toDouble(), true); - dsoSig->set_trig_vrate(obj["trigValue"].toDouble()); + dsoSig->set_zero_ratio(obj["zeroPos"].toDouble()); + dsoSig->set_trig_ratio(obj["trigValue"].toDouble()); dsoSig->commit_settings(); } boost::shared_ptr analogSig; if ((analogSig = dynamic_pointer_cast(s))) { - analogSig->set_zero_vrate(obj["zeroPos"].toDouble(), true); + analogSig->set_zero_ratio(obj["zeroPos"].toDouble()); analogSig->commit_settings(); } @@ -876,9 +999,15 @@ bool MainWindow::load_session(QString name) } #endif + // load measure + if (sessionObj.contains("measure")) { + _view->get_viewstatus()->load_session(sessionObj["measure"].toArray()); + } + return true; } + bool MainWindow::store_session(QString name) { QFile sessionFile(name); @@ -894,7 +1023,7 @@ bool MainWindow::store_session(QString name) } QTextStream outStream(&sessionFile); outStream.setCodec("UTF-8"); - outStream.setGenerateByteOrderMark(true); + //outStream.setGenerateByteOrderMark(true); // UTF-8 without BOM GVariant *gvar_opts; GVariant *gvar; @@ -905,6 +1034,7 @@ bool MainWindow::store_session(QString name) sessionVar["Version"]= QJsonValue::fromVariant(Session_Version); sessionVar["Device"] = QJsonValue::fromVariant(sdi->driver->name); sessionVar["DeviceMode"] = QJsonValue::fromVariant(sdi->mode); + sessionVar["Language"] = QJsonValue::fromVariant(_language); if ((sr_config_list(sdi->driver, sdi, NULL, SR_CONF_DEVICE_SESSIONS, &gvar_opts) != SR_OK)) return false; /* Driver supports no device instance sessions. */ @@ -935,7 +1065,10 @@ bool MainWindow::store_session(QString name) s_obj["type"] = s->get_type(); s_obj["enabled"] = s->enabled(); s_obj["name"] = s->get_name(); - s_obj["colour"] = QJsonValue::fromVariant(s->get_colour()); + if (s->get_colour().isValid()) + s_obj["colour"] = QJsonValue::fromVariant(s->get_colour()); + else + s_obj["colour"] = QJsonValue::fromVariant("default"); boost::shared_ptr logicSig; if ((logicSig = dynamic_pointer_cast(s))) { @@ -948,14 +1081,15 @@ bool MainWindow::store_session(QString name) s_obj["vfactor"] = QJsonValue::fromVariant(static_cast(dsoSig->get_factor())); s_obj["coupling"] = dsoSig->get_acCoupling(); s_obj["trigValue"] = dsoSig->get_trig_vrate(); - s_obj["zeroPos"] = dsoSig->get_zero_vrate(); + s_obj["zeroPos"] = dsoSig->get_zero_ratio(); } boost::shared_ptr analogSig; if ((analogSig = dynamic_pointer_cast(s))) { s_obj["vdiv"] = QJsonValue::fromVariant(static_cast(analogSig->get_vdiv())); + s_obj["vfactor"] = QJsonValue::fromVariant(static_cast(analogSig->get_factor())); s_obj["coupling"] = analogSig->get_acCoupling(); - s_obj["zeroPos"] = analogSig->get_zero_vrate(); + s_obj["zeroPos"] = analogSig->get_zero_ratio(); s_obj["mapUnit"] = analogSig->get_mapUnit(); s_obj["mapMin"] = analogSig->get_mapMin(); s_obj["mapMax"] = analogSig->get_mapMax(); @@ -973,6 +1107,10 @@ bool MainWindow::store_session(QString name) sessionVar["decoder"] = ss.json_decoders(); #endif + if (_session.get_device()->dev_inst()->mode == DSO) { + sessionVar["measure"] = _view->get_viewstatus()->get_session(); + } + QJsonDocument sessionDoc(sessionVar); //sessionFile.write(QString::fromUtf8(sessionDoc.toJson())); outStream << QString::fromUtf8(sessionDoc.toJson()); @@ -980,6 +1118,28 @@ bool MainWindow::store_session(QString name) return true; } +void MainWindow::restore_dock() +{ + // default dockwidget size + QSettings settings(QApplication::organizationName(), QApplication::applicationName()); + restoreState(settings.value("windowState").toByteArray()); + if (_session.get_device()->dev_inst()->mode != DSO) { + _dso_trigger_dock->setVisible(false); + _trig_bar->update_trig_btn(_trigger_dock->isVisible()); + } else { + _trigger_dock->setVisible(false); + _trig_bar->update_trig_btn(_dso_trigger_dock->isVisible()); + } + if (_session.get_device()->dev_inst()->mode != LOGIC) { +#ifdef ENABLE_DECODE + on_protocol(false); +#endif + } + _trig_bar->update_protocol_btn(_protocol_dock->isVisible()); + _trig_bar->update_measure_btn(_measure_dock->isVisible()); + _trig_bar->update_search_btn(_search_dock->isVisible()); +} + bool MainWindow::eventFilter(QObject *object, QEvent *event) { (void) object; @@ -1060,7 +1220,7 @@ bool MainWindow::eventFilter(QObject *object, QEvent *event) shared_ptr dsoSig; if ((dsoSig = dynamic_pointer_cast(s))) { if (dsoSig->get_vDialActive()) { - dsoSig->go_vDialNext(); + dsoSig->go_vDialNext(true); update(); break; } @@ -1072,7 +1232,7 @@ bool MainWindow::eventFilter(QObject *object, QEvent *event) shared_ptr dsoSig; if ((dsoSig = dynamic_pointer_cast(s))) { if (dsoSig->get_vDialActive()) { - dsoSig->go_vDialPre(); + dsoSig->go_vDialPre(true); update(); break; } @@ -1087,4 +1247,57 @@ bool MainWindow::eventFilter(QObject *object, QEvent *event) return false; } +int MainWindow::language() const +{ + return _language; +} + +void MainWindow::switchLanguage(int language) +{ + shared_ptr dev = _session.get_device(); + dev->set_config(NULL, NULL, SR_CONF_LANGUAGE, g_variant_new_int16(language)); + + if (_language != language) { + _language = language; + if (_language != QLocale::English) { + _qtTrans.load(":/qt_"+QString::number(_language)); + qApp->installTranslator(&_qtTrans); + _myTrans.load(":/my_"+QString::number(_language)); + qApp->installTranslator(&_myTrans); + retranslateUi(); + } else { + qApp->removeTranslator(&_qtTrans); + qApp->removeTranslator(&_myTrans); + retranslateUi(); + } + qApp->setProperty("Language", _language); + } +} + +void MainWindow::switchTheme(QString style) +{ + if (_style != style) { + _style = style; + qApp->setProperty("Style", _style); + QString qssRes = ":/"+_style+".qss"; + QFile qss(qssRes); + qss.open(QFile::ReadOnly | QFile::Text); + qApp->setStyleSheet(qss.readAll()); + qss.close(); + _session.data_updated(); + } +} + +void MainWindow::openDoc() +{ + #ifndef Q_OS_LINUX + QDir dir(QCoreApplication::applicationDirPath()); + #else + QDir dir(DS_RES_PATH); + dir.cdUp(); + #endif + QDesktopServices::openUrl( + QUrl("file:///"+dir.absolutePath() + "/ug"+QString::number(_language)+".pdf")); +} + } // namespace pv diff --git a/DSView/pv/mainwindow.h b/DSView/pv/mainwindow.h old mode 100644 new mode 100755 index 9b3c328440d8d3bba92bf928b49789776085c2f5..16272baf1ed9aff634a40170fd578f51408d3d0f --- a/DSView/pv/mainwindow.h +++ b/DSView/pv/mainwindow.h @@ -79,13 +79,19 @@ protected: private: void setup_ui(); - + void retranslateUi(); void session_error(const QString text, const QString info_text); - bool eventFilter(QObject *object, QEvent *event); public slots: void session_save(); + int language() const; + void openDoc(); + + void switchLanguage(int language); + void switchTheme(QString style); + + void restore_dock(); private slots: void load_file(QString file_name); @@ -126,6 +132,7 @@ private slots: void on_export(); bool load_session(QString name); + bool load_session_json(QJsonDocument json, bool file_dev); bool store_session(QString name); /* @@ -138,11 +145,13 @@ private slots: */ void device_attach(); void device_detach(); + void device_changed(bool close); /* * errors */ void show_error(); + signals: void prgRate(int progress); @@ -188,6 +197,11 @@ private: dock::MeasureDock *_measure_widget; QDockWidget *_search_dock; dock::SearchDock * _search_widget; + + int _language; + QString _style; + QTranslator _qtTrans; + QTranslator _myTrans; }; } // namespace pv diff --git a/DSView/pv/prop/binding/binding.cpp b/DSView/pv/prop/binding/binding.cpp old mode 100644 new mode 100755 index d778fd5f648757923ab2dcd0579df8ecc38133fe..c5252716c1bb2532fee294b9db58a61e6d13a3b8 --- a/DSView/pv/prop/binding/binding.cpp +++ b/DSView/pv/prop/binding/binding.cpp @@ -61,7 +61,7 @@ void Binding::add_properties_to_form(QFormLayout *layout, if (p->labeled_widget()) layout->addRow(widget); else - layout->addRow(p->name(), widget); + layout->addRow(p->label(), widget); } } diff --git a/DSView/pv/prop/binding/binding.h b/DSView/pv/prop/binding/binding.h old mode 100644 new mode 100755 diff --git a/DSView/pv/prop/binding/decoderoptions.cpp b/DSView/pv/prop/binding/decoderoptions.cpp old mode 100644 new mode 100755 index 66870403d4ae9577c4b1c70acb05432f9d5230b0..644db938f264615b6cc58b777ddbdf9699ac71f6 --- a/DSView/pv/prop/binding/decoderoptions.cpp +++ b/DSView/pv/prop/binding/decoderoptions.cpp @@ -72,16 +72,16 @@ DecoderOptions::DecoderOptions( shared_ptr prop; if (opt->values) - prop = bind_enum(name, opt, getter, setter); + prop = bind_enum(name, opt, getter, setter); else if (g_variant_is_of_type(opt->def, G_VARIANT_TYPE("d"))) - prop = shared_ptr(new Double(name, 2, "", + prop = shared_ptr(new Double(name, name, 2, "", none, none, getter, setter)); else if (g_variant_is_of_type(opt->def, G_VARIANT_TYPE("x"))) prop = shared_ptr( - new Int(name, "", none, getter, setter)); + new Int(name, name, "", none, getter, setter)); else if (g_variant_is_of_type(opt->def, G_VARIANT_TYPE("s"))) prop = shared_ptr( - new String(name, getter, setter)); + new String(name, name, getter, setter)); else continue; @@ -100,7 +100,7 @@ shared_ptr DecoderOptions::bind_enum( values.push_back(make_pair(var, print_gvariant(var))); } - return shared_ptr(new Enum(name, values, getter, setter)); + return shared_ptr(new Enum(name, name, values, getter, setter)); } GVariant* DecoderOptions::getter(const char *id) diff --git a/DSView/pv/prop/binding/decoderoptions.h b/DSView/pv/prop/binding/decoderoptions.h old mode 100644 new mode 100755 diff --git a/DSView/pv/prop/binding/deviceoptions.cpp b/DSView/pv/prop/binding/deviceoptions.cpp old mode 100644 new mode 100755 index 9a51d50c573a408c59ff7b895ace726857b3eb5b..deef3fac40d5714aade631082948920685fbf4da --- a/DSView/pv/prop/binding/deviceoptions.cpp +++ b/DSView/pv/prop/binding/deviceoptions.cpp @@ -66,16 +66,27 @@ DeviceOptions::DeviceOptions(struct sr_dev_inst *sdi) : if(sr_config_list(_sdi->driver, _sdi, NULL, key, &gvar_list) != SR_OK) gvar_list = NULL; - const QString name(info->label); + const QString name(info->name); + char *label_char = info->label; + GVariant *gvar_tmp = NULL; + if (sr_config_get(_sdi->driver, _sdi, NULL, NULL, SR_CONF_LANGUAGE, &gvar_tmp) == SR_OK) { + if (gvar_tmp != NULL) { + int language = g_variant_get_int16(gvar_tmp); + if (language == QLocale::Chinese) + label_char = info->label_cn; + g_variant_unref(gvar_tmp); + } + } + const QString label(label_char); switch(key) { case SR_CONF_SAMPLERATE: - bind_samplerate(name, gvar_list); + bind_samplerate(name, label, gvar_list); break; case SR_CONF_CAPTURE_RATIO: - bind_int(name, key, "%", pair(0, 100)); + bind_int(name, label, key, "%", pair(0, 100)); break; case SR_CONF_PATTERN_MODE: @@ -94,31 +105,36 @@ DeviceOptions::DeviceOptions(struct sr_dev_inst *sdi) : case SR_CONF_TEST: case SR_CONF_STATUS: case SR_CONF_PROBE_FACTOR: - bind_enum(name, key, gvar_list); + bind_enum(name, label, key, gvar_list); break; case SR_CONF_VTH: - bind_double(name, key, "V", pair(0.0, 5.0), 1, 0.1); + bind_double(name, label, key, "V", pair(0.0, 5.0), 1, 0.1); break; case SR_CONF_RLE: - bind_bool(name, key); + bind_bool(name, label, key); break; case SR_CONF_RLE_SUPPORT: case SR_CONF_CLOCK_TYPE: case SR_CONF_CLOCK_EDGE: case SR_CONF_INSTANT: - bind_bool(name, key); + bind_bool(name, label, key); break; case SR_CONF_TIMEBASE: - bind_enum(name, key, gvar_list, print_timebase); + bind_enum(name, label, key, gvar_list, print_timebase); break; case SR_CONF_PROBE_VDIV: - bind_enum(name, key, gvar_list, print_vdiv); + bind_enum(name, label, key, gvar_list, print_vdiv); break; + + case SR_CONF_BANDWIDTH_LIMIT: + bind_bandwidths(name, label, key, gvar_list); + break; + default: gvar_list = NULL; } @@ -126,7 +142,8 @@ DeviceOptions::DeviceOptions(struct sr_dev_inst *sdi) : if (gvar_list) g_variant_unref(gvar_list); } - g_variant_unref(gvar_opts); + if (gvar_opts) + g_variant_unref(gvar_opts); } GVariant* DeviceOptions::config_getter( @@ -134,8 +151,7 @@ GVariant* DeviceOptions::config_getter( { GVariant *data = NULL; if (sr_config_get(sdi->driver, sdi, NULL, NULL, key, &data) != SR_OK) { - qDebug() << - "WARNING: Failed to get value of config id" << key; + qDebug() << "WARNING: Failed to get value of config id" << key; return NULL; } return data; @@ -145,17 +161,17 @@ void DeviceOptions::config_setter( struct sr_dev_inst *sdi, int key, GVariant* value) { if (sr_config_set(sdi, NULL, NULL, key, value) != SR_OK) - qDebug() << "WARNING: Failed to set value of sample rate"; + qDebug() << "WARNING: Failed to set value of config id" << key; } -void DeviceOptions::bind_bool(const QString &name, int key) +void DeviceOptions::bind_bool(const QString &name, const QString label, int key) { _properties.push_back(boost::shared_ptr( - new Bool(name, bind(config_getter, _sdi, key), + new Bool(name, label, bind(config_getter, _sdi, key), bind(config_setter, _sdi, key, _1)))); } -void DeviceOptions::bind_enum(const QString &name, int key, +void DeviceOptions::bind_enum(const QString &name, const QString label, int key, GVariant *const gvar_list, boost::function printer) { GVariant *gvar; @@ -169,26 +185,26 @@ void DeviceOptions::bind_enum(const QString &name, int key, values.push_back(make_pair(gvar, printer(gvar))); _properties.push_back(boost::shared_ptr( - new Enum(name, values, + new Enum(name, label, values, bind(config_getter, _sdi, key), bind(config_setter, _sdi, key, _1)))); } -void DeviceOptions::bind_int(const QString &name, int key, QString suffix, - optional< std::pair > range) +void DeviceOptions::bind_int(const QString &name, const QString label, int key, QString suffix, + optional< std::pair > range) { _properties.push_back(boost::shared_ptr( - new Int(name, suffix, range, + new Int(name, label, suffix, range, bind(config_getter, _sdi, key), bind(config_setter, _sdi, key, _1)))); } -void DeviceOptions::bind_double(const QString &name, int key, QString suffix, +void DeviceOptions::bind_double(const QString &name, const QString label, int key, QString suffix, optional< std::pair > range, int decimals, boost::optional step) { _properties.push_back(boost::shared_ptr( - new Double(name, decimals, suffix, range, step, + new Double(name, label, decimals, suffix, range, step, bind(config_getter, _sdi, key), bind(config_setter, _sdi, key, _1)))); } @@ -209,8 +225,8 @@ QString DeviceOptions::print_gvariant(GVariant *const gvar) return s; } -void DeviceOptions::bind_samplerate(const QString &name, - GVariant *const gvar_list) +void DeviceOptions::bind_samplerate(const QString &name, const QString label, + GVariant *const gvar_list) { GVariant *gvar_list_samplerates; @@ -227,7 +243,7 @@ void DeviceOptions::bind_samplerate(const QString &name, assert(num_elements == 3); _properties.push_back(boost::shared_ptr( - new Double(name, 0, QObject::tr("Hz"), + new Double(name, label, 0, QObject::tr("Hz"), make_pair((double)elements[0], (double)elements[1]), (double)elements[2], bind(samplerate_double_getter, _sdi), @@ -238,7 +254,7 @@ void DeviceOptions::bind_samplerate(const QString &name, else if ((gvar_list_samplerates = g_variant_lookup_value(gvar_list, "samplerates", G_VARIANT_TYPE("at")))) { - bind_enum(name, SR_CONF_SAMPLERATE, + bind_enum(name, label, SR_CONF_SAMPLERATE, gvar_list_samplerates, print_samplerate); g_variant_unref(gvar_list_samplerates); } @@ -291,6 +307,37 @@ QString DeviceOptions::print_vdiv(GVariant *const gvar) return QString(sr_voltage_string(p, q)); } +void DeviceOptions::bind_bandwidths(const QString &name, const QString label, int key, + GVariant *const gvar_list, boost::function printer) +{ + GVariant *gvar; + GVariantIter iter; + vector< pair > values; + bool bw_limit = FALSE; + + assert(gvar_list); + + GVariant *gvar_tmp = NULL; + if (sr_config_get(_sdi->driver, _sdi, NULL, NULL, SR_CONF_BANDWIDTH, &gvar_tmp) == SR_OK) { + if (gvar_tmp != NULL) { + bw_limit = g_variant_get_boolean(gvar_tmp); + g_variant_unref(gvar_tmp); + } + } + + if (!bw_limit) + return; + + g_variant_iter_init (&iter, gvar_list); + while ((gvar = g_variant_iter_next_value (&iter))) + values.push_back(make_pair(gvar, printer(gvar))); + + _properties.push_back(boost::shared_ptr( + new Enum(name, label, values, + bind(config_getter, _sdi, key), + bind(config_setter, _sdi, key, _1)))); +} + } // binding } // prop } // pv diff --git a/DSView/pv/prop/binding/deviceoptions.h b/DSView/pv/prop/binding/deviceoptions.h old mode 100644 new mode 100755 index 3d52356bea9f67a19ecf430375c73e66b8632342..6de00e81ddedceb54133a066e5b37de1894ab739 --- a/DSView/pv/prop/binding/deviceoptions.h +++ b/DSView/pv/prop/binding/deviceoptions.h @@ -48,20 +48,20 @@ private: static void config_setter( struct sr_dev_inst *sdi, int key, GVariant* value); - void bind_bool(const QString &name, int key); - void bind_enum(const QString &name, int key, + void bind_bool(const QString &name, const QString label, int key); + void bind_enum(const QString &name, const QString label, int key, GVariant *const gvar_list, boost::function printer = print_gvariant); - void bind_int(const QString &name, int key, QString suffix, + void bind_int(const QString &name, const QString label, int key, QString suffix, boost::optional< std::pair > range); - void bind_double(const QString &name, int key, QString suffix, + void bind_double(const QString &name, const QString label, int key, QString suffix, boost::optional > range, int decimals, boost::optional step); static QString print_gvariant(GVariant *const gvar); - void bind_samplerate(const QString &name, + void bind_samplerate(const QString &name, const QString label, GVariant *const gvar_list); static QString print_samplerate(GVariant *const gvar); static GVariant* samplerate_double_getter( @@ -72,6 +72,10 @@ private: static QString print_timebase(GVariant *const gvar); static QString print_vdiv(GVariant *const gvar); + void bind_bandwidths(const QString &name, const QString label, int key, + GVariant *const gvar_list, + boost::function printer = print_gvariant); + protected: struct sr_dev_inst *const _sdi; }; diff --git a/DSView/pv/prop/binding/probeoptions.cpp b/DSView/pv/prop/binding/probeoptions.cpp old mode 100644 new mode 100755 index 594472af68622d9879522041d6a6a6a80c077b7b..3b6a101f5c1db170cd3623ae4bacb99ec8feae2d --- a/DSView/pv/prop/binding/probeoptions.cpp +++ b/DSView/pv/prop/binding/probeoptions.cpp @@ -67,28 +67,43 @@ ProbeOptions::ProbeOptions(struct sr_dev_inst *sdi, if(sr_config_list(_sdi->driver, _sdi, NULL, key, &gvar_list) != SR_OK) gvar_list = NULL; - const QString name(info->label); + const QString name(info->name); + char *label_char = info->label; + GVariant *gvar_tmp = NULL; + if (sr_config_get(_sdi->driver, _sdi, NULL, NULL, SR_CONF_LANGUAGE, &gvar_tmp) == SR_OK) { + if (gvar_tmp != NULL) { + int language = g_variant_get_int16(gvar_tmp); + if (language == QLocale::Chinese) + label_char = info->label_cn; + g_variant_unref(gvar_tmp); + } + } + const QString label(label_char); switch(key) { case SR_CONF_PROBE_VDIV: - bind_vdiv(name, gvar_list); + bind_vdiv(name, label, gvar_list); break; case SR_CONF_PROBE_MAP_MIN: case SR_CONF_PROBE_MAP_MAX: - bind_double(name, key, "", + bind_double(name, label, key, "", pair(-999999.99, 999999.99), 2, 0.01); break; case SR_CONF_PROBE_COUPLING: - bind_coupling(name, gvar_list); + bind_coupling(name, label, gvar_list); break; case SR_CONF_PROBE_MAP_UNIT: - bind_enum(name, key, gvar_list); + bind_enum(name, label, key, gvar_list); break; + case SR_CONF_PROBE_MAP_DEFAULT: + bind_bool(name, label, key); + break; + default: gvar_list = NULL; } @@ -96,7 +111,8 @@ ProbeOptions::ProbeOptions(struct sr_dev_inst *sdi, if (gvar_list) g_variant_unref(gvar_list); } - g_variant_unref(gvar_opts); + if (gvar_opts) + g_variant_unref(gvar_opts); } GVariant* ProbeOptions::config_getter( @@ -120,14 +136,14 @@ void ProbeOptions::config_setter( qDebug() << "WARNING: Failed to set value of sample rate"; } -void ProbeOptions::bind_bool(const QString &name, int key) +void ProbeOptions::bind_bool(const QString &name, const QString label, int key) { _properties.push_back(boost::shared_ptr( - new Bool(name, bind(config_getter, _sdi, _probe, key), + new Bool(name, label, bind(config_getter, _sdi, _probe, key), bind(config_setter, _sdi, _probe, key, _1)))); } -void ProbeOptions::bind_enum(const QString &name, int key, +void ProbeOptions::bind_enum(const QString &name, const QString label, int key, GVariant *const gvar_list, boost::function printer) { GVariant *gvar; @@ -141,32 +157,32 @@ void ProbeOptions::bind_enum(const QString &name, int key, values.push_back(make_pair(gvar, printer(gvar))); _properties.push_back(boost::shared_ptr( - new Enum(name, values, + new Enum(name, label, values, bind(config_getter, _sdi, _probe, key), bind(config_setter, _sdi, _probe, key, _1)))); } -void ProbeOptions::bind_int(const QString &name, int key, QString suffix, - optional< std::pair > range) +void ProbeOptions::bind_int(const QString &name, const QString label, int key, QString suffix, + optional< std::pair > range) { _properties.push_back(boost::shared_ptr( - new Int(name, suffix, range, + new Int(name, label, suffix, range, bind(config_getter, _sdi, _probe, key), bind(config_setter, _sdi, _probe, key, _1)))); } -void ProbeOptions::bind_double(const QString &name, int key, QString suffix, +void ProbeOptions::bind_double(const QString &name, const QString label, int key, QString suffix, optional< std::pair > range, int decimals, boost::optional step) { _properties.push_back(boost::shared_ptr( - new Double(name, decimals, suffix, range, step, + new Double(name, label, decimals, suffix, range, step, bind(config_getter, _sdi, _probe, key), bind(config_setter, _sdi, _probe, key, _1)))); } -void ProbeOptions::bind_vdiv(const QString &name, - GVariant *const gvar_list) +void ProbeOptions::bind_vdiv(const QString &name, const QString label, + GVariant *const gvar_list) { GVariant *gvar_list_vdivs; @@ -175,13 +191,13 @@ void ProbeOptions::bind_vdiv(const QString &name, if ((gvar_list_vdivs = g_variant_lookup_value(gvar_list, "vdivs", G_VARIANT_TYPE("at")))) { - bind_enum(name, SR_CONF_PROBE_VDIV, + bind_enum(name, label, SR_CONF_PROBE_VDIV, gvar_list_vdivs, print_vdiv); g_variant_unref(gvar_list_vdivs); } } -void ProbeOptions::bind_coupling(const QString &name, +void ProbeOptions::bind_coupling(const QString &name, const QString label, GVariant *const gvar_list) { GVariant *gvar_list_coupling; @@ -191,7 +207,7 @@ void ProbeOptions::bind_coupling(const QString &name, if ((gvar_list_coupling = g_variant_lookup_value(gvar_list, "coupling", G_VARIANT_TYPE("ay")))) { - bind_enum(name, SR_CONF_PROBE_COUPLING, + bind_enum(name, label, SR_CONF_PROBE_COUPLING, gvar_list_coupling, print_coupling); g_variant_unref(gvar_list_coupling); } diff --git a/DSView/pv/prop/binding/probeoptions.h b/DSView/pv/prop/binding/probeoptions.h old mode 100644 new mode 100755 index 0bae7efe19d5b3cded54741516cb50770fdad812..3d82c71908f0b2e2a3b8b7971e7ccbf5c88a2e09 --- a/DSView/pv/prop/binding/probeoptions.h +++ b/DSView/pv/prop/binding/probeoptions.h @@ -50,22 +50,22 @@ private: struct sr_dev_inst *sdi, struct sr_channel *probe, int key, GVariant* value); - void bind_bool(const QString &name, int key); - void bind_enum(const QString &name, int key, + void bind_bool(const QString &name, const QString label, int key); + void bind_enum(const QString &name, const QString label, int key, GVariant *const gvar_list, boost::function printer = print_gvariant); - void bind_int(const QString &name, int key, QString suffix, + void bind_int(const QString &name, const QString label, int key, QString suffix, boost::optional< std::pair > range); - void bind_double(const QString &name, int key, QString suffix, + void bind_double(const QString &name, const QString label, int key, QString suffix, boost::optional > range, int decimals, boost::optional step); static QString print_gvariant(GVariant *const gvar); - void bind_vdiv(const QString &name, + void bind_vdiv(const QString &name, const QString label, GVariant *const gvar_list); - void bind_coupling(const QString &name, + void bind_coupling(const QString &name, const QString label, GVariant *const gvar_list); static QString print_vdiv(GVariant *const gvar); diff --git a/DSView/pv/prop/bool.cpp b/DSView/pv/prop/bool.cpp old mode 100644 new mode 100755 index ecc6a2e761cbdff672681c3b1d57df024f2529a5..75169b86a3343dc720c02ef6e8f636faccb128d0 --- a/DSView/pv/prop/bool.cpp +++ b/DSView/pv/prop/bool.cpp @@ -32,8 +32,8 @@ using namespace boost; namespace pv { namespace prop { -Bool::Bool(QString name, Getter getter, Setter setter) : - Property(name, getter, setter), +Bool::Bool(QString name, QString label, Getter getter, Setter setter) : + Property(name, label, getter, setter), _check_box(NULL) { } @@ -47,7 +47,7 @@ QWidget* Bool::get_widget(QWidget *parent, bool auto_commit) if (_check_box) return _check_box; - _check_box = new QCheckBox(name(), parent); + _check_box = new QCheckBox(label(), parent); GVariant *const value = _getter ? _getter() : NULL; diff --git a/DSView/pv/prop/bool.h b/DSView/pv/prop/bool.h old mode 100644 new mode 100755 index ec69217e162048306d84261f2dfefecab92a3ee1..c9f9e4096a26d71ef600cb743144fa5be08906d5 --- a/DSView/pv/prop/bool.h +++ b/DSView/pv/prop/bool.h @@ -35,7 +35,7 @@ class Bool : public Property Q_OBJECT; public: - Bool(QString name, Getter getter, Setter setter); + Bool(QString name, QString label, Getter getter, Setter setter); virtual ~Bool(); diff --git a/DSView/pv/prop/double.cpp b/DSView/pv/prop/double.cpp old mode 100644 new mode 100755 index a0c8cec39d7f28c2c1bf8bba7473980add2125c9..2c832d9ad347e71240d17c0b96cf15aa3f89fd3f --- a/DSView/pv/prop/double.cpp +++ b/DSView/pv/prop/double.cpp @@ -32,14 +32,14 @@ using namespace boost; namespace pv { namespace prop { -Double::Double(QString name, - int decimals, - QString suffix, - optional< pair > range, - optional step, - Getter getter, - Setter setter) : - Property(name, getter, setter), +Double::Double(QString name, QString label, + int decimals, + QString suffix, + optional< pair > range, + optional step, + Getter getter, + Setter setter) : + Property(name, label, getter, setter), _decimals(decimals), _suffix(suffix), _range(range), diff --git a/DSView/pv/prop/double.h b/DSView/pv/prop/double.h old mode 100644 new mode 100755 index 7eb4493d2dcac8a8b14256e8aa7c170acb8cc2df..f80d5170f958ab53ad8e5783e5a6bb95275cd4a3 --- a/DSView/pv/prop/double.h +++ b/DSView/pv/prop/double.h @@ -39,7 +39,7 @@ class Double : public Property Q_OBJECT; public: - Double(QString name, int decimals, QString suffix, + Double(QString name, QString label, int decimals, QString suffix, boost::optional< std::pair > range, boost::optional step, Getter getter, diff --git a/DSView/pv/prop/enum.cpp b/DSView/pv/prop/enum.cpp old mode 100644 new mode 100755 index aad0c08e9c3ee6eb7d54c2bb5984f8a06759e2b0..08d731148d758121edd263e2ce687870bcafc878 --- a/DSView/pv/prop/enum.cpp +++ b/DSView/pv/prop/enum.cpp @@ -33,10 +33,10 @@ using namespace std; namespace pv { namespace prop { -Enum::Enum(QString name, - vector > values, - Getter getter, Setter setter) : - Property(name, getter, setter), +Enum::Enum(QString name, QString label, + vector > values, + Getter getter, Setter setter) : + Property(name, label, getter, setter), _values(values), _selector(NULL) { @@ -48,7 +48,8 @@ Enum::Enum(QString name, Enum::~Enum() { for (unsigned int i = 0; i < _values.size(); i++) - g_variant_unref(_values[i].first); + if (_values[i].first) + g_variant_unref(_values[i].first); } QWidget* Enum::get_widget(QWidget *parent, bool auto_commit) @@ -62,14 +63,12 @@ QWidget* Enum::get_widget(QWidget *parent, bool auto_commit) } _selector = new QComboBox(parent); - _selector->setSizeAdjustPolicy(QComboBox::AdjustToContents); for (unsigned int i = 0; i < _values.size(); i++) { const pair &v = _values[i]; _selector->addItem(v.second, qVariantFromValue((void*)v.first)); if (value && g_variant_compare(v.first, value) == 0) _selector->setCurrentIndex(i); } - _selector->view()->setMinimumWidth(_selector->width()+30); g_variant_unref(value); diff --git a/DSView/pv/prop/enum.h b/DSView/pv/prop/enum.h old mode 100644 new mode 100755 index a223565a77b9483b951c399f9aadd7e52d3c4235..6b1214cd3186aa7af7ebf08600b304d925783948 --- a/DSView/pv/prop/enum.h +++ b/DSView/pv/prop/enum.h @@ -38,7 +38,7 @@ class Enum : public Property Q_OBJECT; public: - Enum(QString name, std::vector > values, + Enum(QString name, QString label, std::vector > values, Getter getter, Setter setter); virtual ~Enum(); diff --git a/DSView/pv/prop/int.cpp b/DSView/pv/prop/int.cpp old mode 100644 new mode 100755 index b3ea0c698355f488bdd5f66018ebcc7b7fdeae23..ac7961eee3af1e033a440be1a88106afaedfe2d4 --- a/DSView/pv/prop/int.cpp +++ b/DSView/pv/prop/int.cpp @@ -49,12 +49,12 @@ using namespace std; namespace pv { namespace prop { -Int::Int(QString name, - QString suffix, - optional< pair > range, - Getter getter, - Setter setter) : - Property(name, getter, setter), +Int::Int(QString name, QString label, + QString suffix, + optional< pair > range, + Getter getter, + Setter setter) : + Property(name, label, getter, setter), _suffix(suffix), _range(range), _value(NULL), diff --git a/DSView/pv/prop/int.h b/DSView/pv/prop/int.h old mode 100644 new mode 100755 index daa4c1d3e5a78216787962aabf22345587459513..0e747540f8dede460f1fd8b2db1be336ea5e5315 --- a/DSView/pv/prop/int.h +++ b/DSView/pv/prop/int.h @@ -39,7 +39,7 @@ class Int : public Property Q_OBJECT; public: - Int(QString name, QString suffix, + Int(QString name, QString label, QString suffix, boost::optional< std::pair > range, Getter getter, Setter setter); diff --git a/DSView/pv/prop/property.cpp b/DSView/pv/prop/property.cpp old mode 100644 new mode 100755 index af37d644fddbba6ec566380f082eb60bc01b5851..de7150b5723074b32ad0c0ccbf874dc7b15496cd --- a/DSView/pv/prop/property.cpp +++ b/DSView/pv/prop/property.cpp @@ -25,10 +25,11 @@ namespace pv { namespace prop { -Property::Property(QString name, Getter getter, Setter setter) : +Property::Property(QString name, QString label, Getter getter, Setter setter) : _getter(getter), _setter(setter), - _name(name) + _name(name), + _label(label) { } @@ -37,6 +38,11 @@ const QString& Property::name() const return _name; } +const QString& Property::label() const +{ + return _label; +} + bool Property::labeled_widget() const { return false; diff --git a/DSView/pv/prop/property.h b/DSView/pv/prop/property.h old mode 100644 new mode 100755 index 117ba9a16d3b93873c72264d014ecb9901cbe7e8..2868eedb6ac53ffcfb37dcd2f1fcbc7366344e8a --- a/DSView/pv/prop/property.h +++ b/DSView/pv/prop/property.h @@ -44,10 +44,11 @@ public: typedef boost::function Setter; protected: - Property(QString name, Getter getter, Setter setter); + Property(QString name, QString label, Getter getter, Setter setter); public: const QString& name() const; + const QString& label() const; virtual QWidget* get_widget(QWidget *parent, bool auto_commit = false) = 0; @@ -63,6 +64,7 @@ protected: private: QString _name; + QString _label; }; } // prop diff --git a/DSView/pv/prop/string.cpp b/DSView/pv/prop/string.cpp old mode 100644 new mode 100755 index e03064ef9e4bc366bae6456728bf9cb13cc5868b..c57525e601da6cc79e6a3811592037b25c0c02d4 --- a/DSView/pv/prop/string.cpp +++ b/DSView/pv/prop/string.cpp @@ -28,10 +28,10 @@ namespace pv { namespace prop { -String::String(QString name, +String::String(QString name, QString label, Getter getter, Setter setter) : - Property(name, getter, setter), + Property(name, label, getter, setter), _line_edit(NULL) { } diff --git a/DSView/pv/prop/string.h b/DSView/pv/prop/string.h old mode 100644 new mode 100755 index 7be058d23ca935505d9dc7a177f67e56a71826ab..ef788c7f0e76feef3cd910648b97712ad249cea3 --- a/DSView/pv/prop/string.h +++ b/DSView/pv/prop/string.h @@ -33,7 +33,7 @@ class String : public Property Q_OBJECT; public: - String(QString name, Getter getter, Setter setter); + String(QString name, QString label, Getter getter, Setter setter); QWidget* get_widget(QWidget *parent, bool auto_commit); diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp old mode 100644 new mode 100755 index a44d920fd7c4a64b9408de2712b6e73b83f3c115..d40b52179a1c85e84b7d22f8ed14725dd64f4fad --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -41,6 +41,7 @@ #include "data/decoderstack.h" #include "data/decode/decoder.h" #include "data/decodermodel.h" +#include "data/spectrumstack.h" #include "data/mathstack.h" #include "view/analogsignal.h" @@ -48,6 +49,8 @@ #include "view/logicsignal.h" #include "view/groupsignal.h" #include "view/decodetrace.h" +#include "view/spectrumtrace.h" +#include "view/lissajoustrace.h" #include "view/mathtrace.h" #include @@ -109,6 +112,9 @@ SigSession::SigSession(DeviceManager &device_manager) : #ifdef ENABLE_DECODE _decoder_model = new pv::data::DecoderModel(this); #endif + _lissajous_trace = NULL; + _math_trace = NULL; + _dso_feed = false; // Create snapshots & data containers _cur_logic_snapshot.reset(new data::LogicSnapshot()); @@ -148,7 +154,7 @@ boost::shared_ptr SigSession::get_device() const return _dev_inst; } -void SigSession::set_device(boost::shared_ptr dev_inst) throw(QString) +void SigSession::set_device(boost::shared_ptr dev_inst) { using pv::device::Device; @@ -186,7 +192,7 @@ void SigSession::set_device(boost::shared_ptr dev_inst) throw(Q } -void SigSession::set_file(QString name) throw(QString) +void SigSession::set_file(QString name) { // Deslect the old device, because file type detection in File::create // destorys the old session inside libsigrok. @@ -204,6 +210,21 @@ void SigSession::set_file(QString name) throw(QString) } } +void SigSession::close_file(boost::shared_ptr dev_inst) +{ + assert(dev_inst); + try { + dev_inst->device_updated(); + set_repeating(false); + stop_capture(); + capture_state_changed(SigSession::Stopped); + _device_manager.del_device(dev_inst); + } catch(const QString e) { + throw(e); + return; + } +} + void SigSession::set_default_device(boost::function error_handler) { boost::shared_ptr default_device; @@ -274,8 +295,8 @@ void SigSession::set_cur_samplerate(uint64_t samplerate) _logic_data->set_samplerate(_cur_samplerate); if (_analog_data) _analog_data->set_samplerate(_cur_samplerate); - if (_dso_data) - _dso_data->set_samplerate(_cur_samplerate); +// if (_dso_data) +// _dso_data->set_samplerate(_cur_samplerate); // Group if (_group_data) _group_data->set_samplerate(_cur_samplerate); @@ -285,9 +306,9 @@ void SigSession::set_cur_samplerate(uint64_t samplerate) BOOST_FOREACH(const boost::shared_ptr d, _decode_traces) d->decoder()->set_samplerate(_cur_samplerate); #endif - // MathStack - BOOST_FOREACH(const boost::shared_ptr m, _math_traces) - m->get_math_stack()->set_samplerate(_cur_samplerate); + // SpectrumStack + BOOST_FOREACH(const boost::shared_ptr m, _spectrum_traces) + m->get_spectrum_stack()->set_samplerate(_cur_samplerate); cur_samplerate_changed(); } @@ -328,11 +349,11 @@ void SigSession::capture_init() assert(s); boost::shared_ptr dsoSig; if ((dsoSig = dynamic_pointer_cast(s))) { - dsoSig->set_zero_vrate(dsoSig->get_zero_vrate(), true); + dsoSig->set_zero_ratio(dsoSig->get_zero_ratio()); } boost::shared_ptr analogSig; if ((analogSig = dynamic_pointer_cast(s))) { - analogSig->set_zero_vrate(analogSig->get_zero_vrate(), true); + analogSig->set_zero_ratio(analogSig->get_zero_ratio()); } } } @@ -355,13 +376,16 @@ void SigSession::container_init() if (_dso_data) _dso_data->init(); - // MathStack - BOOST_FOREACH(const boost::shared_ptr m, _math_traces) + // SpectrumStack + BOOST_FOREACH(const boost::shared_ptr m, _spectrum_traces) { assert(m); - m->get_math_stack()->init(); + m->get_spectrum_stack()->init(); } + if (_math_trace) + _math_trace->get_math_stack()->init(); + #ifdef ENABLE_DECODE // DecoderModel //pv::data::DecoderModel *decoder_model = get_decoder_model(); @@ -437,6 +461,7 @@ void SigSession::stop_capture() #endif if (get_capture_state() != Running) return; + sr_session_stop(); // Check that sampling stopped @@ -711,7 +736,9 @@ void SigSession::init_signals() _signals = sigs; } - mathTraces_rebuild(); + spectrum_rebuild(); + lissajous_disable(); + math_disable(); //data_updated(); } @@ -788,7 +815,7 @@ void SigSession::reload() } } - mathTraces_rebuild(); + spectrum_rebuild(); } void SigSession::refresh(int holdtime) @@ -796,7 +823,6 @@ void SigSession::refresh(int holdtime) boost::lock_guard lock(_data_mutex); data_lock(); - QTimer::singleShot(holdtime, this, SLOT(data_unlock())); if (_logic_data) { _logic_data->init(); @@ -811,17 +837,21 @@ void SigSession::refresh(int holdtime) } if (_dso_data) { _dso_data->init(); - // MathStack - BOOST_FOREACH(const boost::shared_ptr m, _math_traces) + // SpectrumStack + BOOST_FOREACH(const boost::shared_ptr m, _spectrum_traces) { assert(m); - m->get_math_stack()->init(); + m->get_spectrum_stack()->init(); } + if (_math_trace) + _math_trace->get_math_stack()->init(); } if (_analog_data) { _analog_data->init(); //_cur_analog_snapshot.reset(); } + + QTimer::singleShot(holdtime, this, SLOT(data_unlock())); //data_updated(); _data_updated = true; } @@ -860,20 +890,6 @@ void SigSession::feed_in_header(const sr_dev_inst *sdi) { (void)sdi; _trigger_pos = 0; - _trigger_time = QDateTime::currentDateTime(); - const int64_t secs = -cur_sampletime(); - _trigger_time = _trigger_time.addSecs(secs); - - if (_dev_inst->name() == "virtual-session") { - int64_t time; - GVariant* gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_TRIGGER_TIME); - if (gvar != NULL) { - time = g_variant_get_int64(gvar); - g_variant_unref(gvar); - if (time != 0) - _trigger_time = QDateTime::fromMSecsSinceEpoch(time); - } - } receive_header(); } @@ -905,12 +921,6 @@ void SigSession::feed_in_trigger(const ds_trigger_pos &trigger_pos) _trigger_pos = trigger_pos.real_pos; receive_trigger(_trigger_pos); } - if (_dev_inst->name() != "virtual-session") { - const double time = trigger_pos.real_pos * 1.0 / _cur_samplerate; - _trigger_time = QDateTime::currentDateTime(); - const int64_t secs = time - cur_sampletime(); - _trigger_time = _trigger_time.addSecs(secs); - } } else { int probe_count = 0; int probe_en_count = 0; @@ -951,7 +961,7 @@ void SigSession::feed_in_logic(const sr_datafeed_logic &logic) frame_began(); } else { // Append to the existing data snapshot - _cur_logic_snapshot->append_payload(logic); + _cur_logic_snapshot->append_payload(logic); } if (_cur_logic_snapshot->memory_failed()) { @@ -996,18 +1006,31 @@ void SigSession::feed_in_dso(const sr_datafeed_dso &dso) // Append to the existing data snapshot _cur_dso_snapshot->append_payload(dso); } + + if (dso.num_samples != 0) { + if (_dso_data) + _dso_data->set_samplerate(_dev_inst->get_sample_rate()); + set_dso_feed(true); + } + if (_cur_dso_snapshot->memory_failed()) { _error = Malloc_err; session_error(); return; } - // calculate related math results - BOOST_FOREACH(const boost::shared_ptr m, _math_traces) + // calculate related spectrum results + BOOST_FOREACH(const boost::shared_ptr m, _spectrum_traces) { assert(m); if (m->enabled()) - m->get_math_stack()->calc_fft(); + m->get_spectrum_stack()->calc_fft(); + } + + // calculate related math results + if (_math_trace && _math_trace->enabled()) { + _math_trace->get_math_stack()->realloc(_dev_inst->get_sample_limit()); + _math_trace->get_math_stack()->calc_math(); } _trigger_flag = dso.trig_flag; @@ -1030,6 +1053,16 @@ void SigSession::feed_in_analog(const sr_datafeed_analog &analog) if (_cur_analog_snapshot->last_ended()) { + // reset scale of analog signal + BOOST_FOREACH(const boost::shared_ptr s, _signals) + { + assert(s); + boost::shared_ptr analogSig; + if ((analogSig = dynamic_pointer_cast(s))) { + analogSig->set_scale(analogSig->get_totalHeight()); + } + } + // first payload _cur_analog_snapshot->first_payload(analog, _dev_inst->get_sample_limit(), _dev_inst->dev_inst()->channels); } else { @@ -1421,7 +1454,7 @@ pv::data::DecoderModel* SigSession::get_decoder_model() const } #endif -void SigSession::mathTraces_rebuild() +void SigSession::spectrum_rebuild() { bool has_dso_signal = false; BOOST_FOREACH(const boost::shared_ptr s, _signals) { @@ -1429,31 +1462,82 @@ void SigSession::mathTraces_rebuild() if ((dsoSig = dynamic_pointer_cast(s))) { has_dso_signal = true; // check already have - std::vector< boost::shared_ptr >::iterator iter = _math_traces.begin(); - for(unsigned int i = 0; i < _math_traces.size(); i++, iter++) + std::vector< boost::shared_ptr >::iterator iter = _spectrum_traces.begin(); + for(unsigned int i = 0; i < _spectrum_traces.size(); i++, iter++) if ((*iter)->get_index() == dsoSig->get_index()) break; // if not, rebuild - if (iter == _math_traces.end()) { - boost::shared_ptr math_stack( - new data::MathStack(*this, dsoSig->get_index())); - boost::shared_ptr math_trace( - new view::MathTrace(*this, math_stack, dsoSig->get_index())); - _math_traces.push_back(math_trace); + if (iter == _spectrum_traces.end()) { + boost::shared_ptr spectrum_stack( + new data::SpectrumStack(*this, dsoSig->get_index())); + boost::shared_ptr spectrum_trace( + new view::SpectrumTrace(*this, spectrum_stack, dsoSig->get_index())); + _spectrum_traces.push_back(spectrum_trace); } } } if (!has_dso_signal) - _math_traces.clear(); + _spectrum_traces.clear(); signals_changed(); } -vector< boost::shared_ptr > SigSession::get_math_signals() +vector< boost::shared_ptr > SigSession::get_spectrum_traces() { //lock_guard lock(_signals_mutex); - return _math_traces; + return _spectrum_traces; +} + +void SigSession::lissajous_rebuild(bool enable, int xindex, int yindex, double percent) +{ + _lissajous_trace.reset(new view::LissajousTrace(enable, _dso_data, xindex, yindex, percent)); + signals_changed(); +} + +void SigSession::lissajous_disable() +{ + if (_lissajous_trace) + _lissajous_trace->set_enable(false); +} + +boost::shared_ptr SigSession::get_lissajous_trace() +{ + //lock_guard lock(_signals_mutex); + return _lissajous_trace; +} + +void SigSession::math_rebuild(bool enable, + boost::shared_ptr dsoSig1, + boost::shared_ptr dsoSig2, + data::MathStack::MathType type) +{ + boost::lock_guard lock(_data_mutex); + boost::shared_ptr math_stack( + new data::MathStack(*this, dsoSig1, dsoSig2, type)); + _math_trace.reset(new view::MathTrace(enable, math_stack, dsoSig1, dsoSig2)); + if (_math_trace && _math_trace->enabled()) { + _math_trace->get_math_stack()->realloc(_dev_inst->get_sample_limit()); + _math_trace->get_math_stack()->calc_math(); + } + signals_changed(); +} + +void SigSession::math_disable() +{ + if (_math_trace) + _math_trace->set_enable(false); +} + +boost::shared_ptr SigSession::get_math_trace() +{ + //lock_guard lock(_signals_mutex); + return _math_trace; +} + +void SigSession::set_trigger_time(QDateTime time) +{ + _trigger_time = time; } QDateTime SigSession::get_trigger_time() const @@ -1594,4 +1678,44 @@ int SigSession::get_map_zoom() const return _map_zoom; } +void SigSession::auto_end() +{ + BOOST_FOREACH(const boost::shared_ptr s, _signals) { + boost::shared_ptr dsoSig; + if ((dsoSig = dynamic_pointer_cast(s))) { + dsoSig->auto_end(); + } + } +} + +void SigSession::set_save_start(uint64_t start) +{ + _save_start = start; +} + +void SigSession::set_save_end(uint64_t end) +{ + _save_end = end; +} + +uint64_t SigSession::get_save_start() const +{ + return _save_start; +} + +uint64_t SigSession::get_save_end() const +{ + return _save_end; +} + +bool SigSession::dso_feed() const +{ + return _dso_feed; +} + +void SigSession::set_dso_feed(bool feed) +{ + _dso_feed = feed; +} + } // namespace pv diff --git a/DSView/pv/sigsession.h b/DSView/pv/sigsession.h old mode 100644 new mode 100755 index a22d020cfd1840dbafc54438f2c524a8e3c21bef..9295d7593f8e49fc174c2096553c05ba9b8da32e --- a/DSView/pv/sigsession.h +++ b/DSView/pv/sigsession.h @@ -49,6 +49,9 @@ #include #include +#include "view/mathtrace.h" +#include "data/mathstack.h" + struct srd_decoder; struct srd_channel; @@ -68,6 +71,7 @@ class LogicSnapshot; class Group; class GroupSnapshot; class DecoderModel; +class MathStack; } namespace device { @@ -78,6 +82,8 @@ namespace view { class Signal; class GroupSignal; class DecodeTrace; +class SpectrumTrace; +class LissajousTrace; class MathTrace; } @@ -131,11 +137,11 @@ public: /** * Sets device instance that will be used in the next capture session. */ - void set_device(boost::shared_ptr dev_inst) - throw(QString); + void set_device(boost::shared_ptr dev_inst); + + void set_file(QString name); - void set_file(QString name) - throw(QString); + void close_file(boost::shared_ptr dev_inst); void set_default_device(boost::function error_handler); @@ -148,6 +154,7 @@ public: double cur_sampletime() const; void set_cur_samplerate(uint64_t samplerate); void set_cur_samplelimits(uint64_t samplelimits); + void set_trigger_time(QDateTime time); QDateTime get_trigger_time() const; uint64_t get_trigger_pos() const; @@ -182,8 +189,14 @@ public: pv::data::DecoderModel* get_decoder_model() const; #endif - std::vector< boost::shared_ptr > - get_math_signals(); + std::vector< boost::shared_ptr > + get_spectrum_traces(); + + boost::shared_ptr + get_lissajous_trace(); + + boost::shared_ptr + get_math_trace(); void init_signals(); @@ -204,7 +217,14 @@ public: void data_auto_lock(int lock); void data_auto_unlock(); bool get_data_auto_lock(); - void mathTraces_rebuild(); + void spectrum_rebuild(); + void lissajous_rebuild(bool enable, int xindex, int yindex, double percent); + void lissajous_disable(); + void math_rebuild(bool enable, + boost::shared_ptr dsoSig1, + boost::shared_ptr dsoSig2, + data::MathStack::MathType type); + void math_disable(); bool trigd() const; @@ -225,6 +245,14 @@ public: int get_map_zoom() const; + void set_save_start(uint64_t start); + void set_save_end(uint64_t end); + uint64_t get_save_start() const; + uint64_t get_save_end() const; + + bool dso_feed() const; + void set_dso_feed(bool feed); + private: void set_capture_state(capture_state state); @@ -286,7 +314,9 @@ private: std::vector< boost::shared_ptr > _decode_traces; pv::data::DecoderModel *_decoder_model; #endif - std::vector< boost::shared_ptr > _math_traces; + std::vector< boost::shared_ptr > _spectrum_traces; + boost::shared_ptr _lissajous_trace; + boost::shared_ptr _math_trace; mutable boost::mutex _data_mutex; boost::shared_ptr _logic_data; @@ -327,6 +357,11 @@ private: int _map_zoom; + uint64_t _save_start; + uint64_t _save_end; + + bool _dso_feed; + signals: void capture_state_changed(int state); @@ -380,6 +415,8 @@ public slots: // repeat void set_repeating(bool repeat); void set_map_zoom(int index); + // OSC auto + void auto_end(); private slots: void data_lock(); diff --git a/DSView/pv/storesession.cpp b/DSView/pv/storesession.cpp old mode 100644 new mode 100755 index 9c3591092673e648ac495390574821fdc145c2f8..e3834402b0fdf6e74dd19ed4a330f72c42798b14 --- a/DSView/pv/storesession.cpp +++ b/DSView/pv/storesession.cpp @@ -42,6 +42,7 @@ #include +#include #include using boost::dynamic_pointer_cast; @@ -115,7 +116,7 @@ QList StoreSession::getSuportedExportFormats(){ return list; } -bool StoreSession::save_start() +bool StoreSession::save_start(QString session_file) { std::set type_set; BOOST_FOREACH(const boost::shared_ptr sig, _session.get_signals()) { @@ -141,7 +142,7 @@ bool StoreSession::save_start() } const QString DIR_KEY("SavePath"); - QSettings settings; + QSettings settings(QApplication::organizationName(), QApplication::applicationName()); // Show the dialog _file_name = QFileDialog::getSaveFileName( @@ -167,7 +168,8 @@ bool StoreSession::save_start() } else { int ret = sr_session_save_init(_file_name.toLocal8Bit().data(), meta_file.toLocal8Bit().data(), - decoders_file.toLocal8Bit().data()); + decoders_file.toLocal8Bit().data(), + session_file.toLocal8Bit().data()); if (ret != SR_OK) { _error = tr("Failed to create zip file. Please check write permission of this path."); return false; @@ -186,6 +188,7 @@ void StoreSession::save_proc(shared_ptr snapshot) { assert(snapshot); + int ret = SR_ERR; shared_ptr logic_snapshot; shared_ptr analog_snapshot; shared_ptr dso_snapshot; @@ -214,13 +217,21 @@ void StoreSession::save_proc(shared_ptr snapshot) buf = (uint8_t *)malloc(size); if (buf == NULL) { _has_error = true; - _error = tr("Malloc failed."); - return; + _error = tr("Failed to create zip file. Malloc error."); + } else { + memset(buf, sample ? 0xff : 0x0, size); } - memset(buf, sample ? 0xff : 0x0, size); } - sr_session_append(_file_name.toLocal8Bit().data(), buf, size, + ret = sr_session_append(_file_name.toLocal8Bit().data(), buf, size, i, ch_index, ch_type, File_Version); + if (ret != SR_OK) { + if (!_has_error) { + _has_error = true; + _error = tr("Failed to create zip file. Please check write permission of this path."); + } + progress_updated(); + return; + } _units_stored += size; if (need_malloc) free(buf); @@ -250,26 +261,34 @@ void StoreSession::save_proc(shared_ptr snapshot) uint8_t *tmp = (uint8_t *)malloc(size); if (tmp == NULL) { _has_error = true; - _error = tr("Malloc failed."); - return; + _error = tr("Failed to create zip file. Malloc error."); + } else { + memcpy(tmp, buf, buf_end-buf); + memcpy(tmp+(buf_end-buf), buf_start, buf+size-buf_end); } - memcpy(tmp, buf, buf_end-buf); - memcpy(tmp+(buf_end-buf), buf_start, buf+size-buf_end); - sr_session_append(_file_name.toLocal8Bit().data(), tmp, size, + ret = sr_session_append(_file_name.toLocal8Bit().data(), tmp, size, i, 0, ch_type, File_Version); buf += (size - _unit_count); - free(tmp); + if (tmp) + free(tmp); } else { - sr_session_append(_file_name.toLocal8Bit().data(), buf, size, + ret = sr_session_append(_file_name.toLocal8Bit().data(), buf, size, i, 0, ch_type, File_Version); buf += size; } + if (ret != SR_OK) { + if (!_has_error) { + _has_error = true; + _error = tr("Failed to create zip file. Please check write permission of this path."); + } + progress_updated(); + return; + } _units_stored += size; progress_updated(); } } } - progress_updated(); } @@ -306,14 +325,9 @@ QString StoreSession::meta_gen(boost::shared_ptr snapshot) } fprintf(meta, "[version]\n"); -// if (sdi->mode != LOGIC) -// fprintf(meta, "version = %d\n", 1); // should be updated in next version -// else -// fprintf(meta, "version = %d\n", File_Version); fprintf(meta, "version = %d\n", File_Version); /* metadata */ - fprintf(meta, "[header]\n"); if (sdi->driver) { fprintf(meta, "driver = %s\n", sdi->driver->name); @@ -357,6 +371,18 @@ QString StoreSession::meta_gen(boost::shared_ptr snapshot) fprintf(meta, "bits = %d\n", tmp_u8); g_variant_unref(gvar); } + gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_REF_MIN); + if (gvar != NULL) { + uint32_t tmp_u32 = g_variant_get_uint32(gvar); + fprintf(meta, "ref min = %d\n", tmp_u32); + g_variant_unref(gvar); + } + gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_REF_MAX); + if (gvar != NULL) { + uint32_t tmp_u32 = g_variant_get_uint32(gvar); + fprintf(meta, "ref max = %d\n", tmp_u32); + g_variant_unref(gvar); + } } else if (sdi->mode == LOGIC) { fprintf(meta, "trigger time = %lld\n", _session.get_trigger_time().toMSecsSinceEpoch()); } else if (sdi->mode == ANALOG) { @@ -365,6 +391,18 @@ QString StoreSession::meta_gen(boost::shared_ptr snapshot) uint8_t tmp_u8 = analog_snapshot->get_unit_bytes(); fprintf(meta, "bits = %d\n", tmp_u8*8); } + gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_REF_MIN); + if (gvar != NULL) { + uint32_t tmp_u32 = g_variant_get_uint32(gvar); + fprintf(meta, "ref min = %d\n", tmp_u32); + g_variant_unref(gvar); + } + gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_REF_MAX); + if (gvar != NULL) { + uint32_t tmp_u32 = g_variant_get_uint32(gvar); + fprintf(meta, "ref max = %d\n", tmp_u32); + g_variant_unref(gvar); + } } fprintf(meta, "trigger pos = %" PRIu64 "\n", _session.get_trigger_pos()); @@ -372,6 +410,9 @@ QString StoreSession::meta_gen(boost::shared_ptr snapshot) for (l = sdi->channels; l; l = l->next) { probe = (struct sr_channel *)l->data; if (snapshot->has_data(probe->index)) { + if (sdi->mode == LOGIC && !probe->enabled) + continue; + if (probe->name) fprintf(meta, "probe%d = %s\n", (sdi->mode == LOGIC) ? probe->index : probecnt, probe->name); if (probe->trigger) @@ -380,27 +421,47 @@ QString StoreSession::meta_gen(boost::shared_ptr snapshot) fprintf(meta, " enable%d = %d\n", probecnt, probe->enabled); fprintf(meta, " coupling%d = %d\n", probecnt, probe->coupling); fprintf(meta, " vDiv%d = %" PRIu64 "\n", probecnt, probe->vdiv); - fprintf(meta, " vFactor%d = %d\n", probecnt, probe->vfactor); - fprintf(meta, " vPos%d = %lf\n", probecnt, probe->vpos); + fprintf(meta, " vFactor%d = %" PRIu64 "\n", probecnt, probe->vfactor); + fprintf(meta, " vOffset%d = %d\n", probecnt, probe->hw_offset); fprintf(meta, " vTrig%d = %d\n", probecnt, probe->trig_value); if (sr_status_get(sdi, &status, false, 0, 0) == SR_OK) { if (probe->index == 0) { - fprintf(meta, " period%d = %" PRIu64 "\n", probecnt, status.ch0_period); - fprintf(meta, " pcnt%d = %" PRIu32 "\n", probecnt, status.ch0_pcnt); + fprintf(meta, " period%d = %" PRIu32 "\n", probecnt, status.ch0_cyc_tlen); + fprintf(meta, " pcnt%d = %" PRIu32 "\n", probecnt, status.ch0_cyc_cnt); fprintf(meta, " max%d = %d\n", probecnt, status.ch0_max); fprintf(meta, " min%d = %d\n", probecnt, status.ch0_min); + fprintf(meta, " plen%d = %" PRIu32 "\n", probecnt, status.ch0_cyc_plen); + fprintf(meta, " llen%d = %" PRIu32 "\n", probecnt, status.ch0_cyc_llen); + fprintf(meta, " level%d = %d\n", probecnt, status.ch0_level_valid); + fprintf(meta, " plevel%d = %d\n", probecnt, status.ch0_plevel); + fprintf(meta, " low%d = %" PRIu32 "\n", probecnt, status.ch0_low_level); + fprintf(meta, " high%d = %" PRIu32 "\n", probecnt, status.ch0_high_level); + fprintf(meta, " rlen%d = %" PRIu32 "\n", probecnt, status.ch0_cyc_rlen); + fprintf(meta, " flen%d = %" PRIu32 "\n", probecnt, status.ch0_cyc_flen); + fprintf(meta, " rms%d = %" PRIu64 "\n", probecnt, status.ch0_acc_square); + fprintf(meta, " mean%d = %" PRIu32 "\n", probecnt, status.ch0_acc_mean); } else { - fprintf(meta, " period%d = %" PRIu64 "\n", probecnt, status.ch1_period); - fprintf(meta, " pcnt%d = %" PRIu32 "\n", probecnt, status.ch1_pcnt); + fprintf(meta, " period%d = %" PRIu32 "\n", probecnt, status.ch1_cyc_tlen); + fprintf(meta, " pcnt%d = %" PRIu32 "\n", probecnt, status.ch1_cyc_cnt); fprintf(meta, " max%d = %d\n", probecnt, status.ch1_max); fprintf(meta, " min%d = %d\n", probecnt, status.ch1_min); + fprintf(meta, " plen%d = %" PRIu32 "\n", probecnt, status.ch1_cyc_plen); + fprintf(meta, " llen%d = %" PRIu32 "\n", probecnt, status.ch1_cyc_llen); + fprintf(meta, " level%d = %d\n", probecnt, status.ch1_level_valid); + fprintf(meta, " plevel%d = %d\n", probecnt, status.ch1_plevel); + fprintf(meta, " low%d = %" PRIu32 "\n", probecnt, status.ch1_low_level); + fprintf(meta, " high%d = %" PRIu32 "\n", probecnt, status.ch1_high_level); + fprintf(meta, " rlen%d = %" PRIu32 "\n", probecnt, status.ch1_cyc_rlen); + fprintf(meta, " flen%d = %" PRIu32 "\n", probecnt, status.ch1_cyc_flen); + fprintf(meta, " rms%d = %" PRIu64 "\n", probecnt, status.ch1_acc_square); + fprintf(meta, " mean%d = %" PRIu32 "\n", probecnt, status.ch1_acc_mean); } } } else if (sdi->mode == ANALOG) { fprintf(meta, " enable%d = %d\n", probecnt, probe->enabled); fprintf(meta, " coupling%d = %d\n", probecnt, probe->coupling); fprintf(meta, " vDiv%d = %" PRIu64 "\n", probecnt, probe->vdiv); - fprintf(meta, " vPos%d = %lf\n", probecnt, probe->vpos); + fprintf(meta, " vOffset%d = %d\n", probecnt, probe->hw_offset); fprintf(meta, " mapUnit%d = %s\n", probecnt, probe->map_unit); fprintf(meta, " mapMax%d = %lf\n", probecnt, probe->map_max); fprintf(meta, " mapMin%d = %lf\n", probecnt, probe->map_min); @@ -440,7 +501,7 @@ bool StoreSession::export_start() } const QString DIR_KEY("ExportPath"); - QSettings settings; + QSettings settings(QApplication::organizationName(), QApplication::applicationName()); // Show the dialog QList supportedFormats = getSuportedExportFormats(); @@ -521,7 +582,7 @@ void StoreSession::export_proc(shared_ptr snapshot) file.open(QIODevice::WriteOnly | QIODevice::Text); QTextStream out(&file); out.setCodec("UTF-8"); - out.setGenerateByteOrderMark(true); + //out.setGenerateByteOrderMark(true); // UTF-8 without BOM // Meta GString *data_out; @@ -664,7 +725,8 @@ void StoreSession::export_proc(shared_ptr snapshot) file.close(); _outModule->cleanup(&output); g_hash_table_destroy(params); - g_variant_unref(filenameGVariant); + if (filenameGVariant != NULL) + g_variant_unref(filenameGVariant); progress_updated(); } @@ -689,7 +751,7 @@ QString StoreSession::decoders_gen() } QTextStream outStream(&sessionFile); outStream.setCodec("UTF-8"); - outStream.setGenerateByteOrderMark(true); + //outStream.setGenerateByteOrderMark(true); // UTF-8 without BOM QJsonArray dec_array = json_decoders(); QJsonDocument sessionDoc(dec_array); @@ -733,32 +795,24 @@ QJsonArray StoreSession::json_decoders() const srd_decoder_option *const opt = (srd_decoder_option*)l->data; - const std::map& options = dec->options(); - std::map::const_iterator iter = options.find(opt->id); - if (opt->values) { - for (GSList *vl = opt->values; vl; vl = vl->next) { - GVariant *const var = (GVariant*)vl->data; - assert(var); - if (iter == options.end()) { - options_obj[opt->id] = QJsonValue::fromVariant(dec_binding->print_gvariant(opt->def)); - break; - } else if (g_variant_compare((*iter).second, var) == 0) { - options_obj[opt->id] = QJsonValue::fromVariant(dec_binding->print_gvariant(var)); - break; - } - } - } else if (g_variant_is_of_type(opt->def, G_VARIANT_TYPE("d"))) { + if (g_variant_is_of_type(opt->def, G_VARIANT_TYPE("d"))) { GVariant *const var = dec_binding->getter(opt->id); - options_obj[opt->id] = QJsonValue::fromVariant(g_variant_get_double(var)); - g_variant_unref(var); + if (var != NULL) { + options_obj[opt->id] = QJsonValue::fromVariant(g_variant_get_double(var)); + g_variant_unref(var); + } } else if (g_variant_is_of_type(opt->def, G_VARIANT_TYPE("x"))) { GVariant *const var = dec_binding->getter(opt->id); - options_obj[opt->id] = QJsonValue::fromVariant(get_double(var)); - g_variant_unref(var); + if (var != NULL) { + options_obj[opt->id] = QJsonValue::fromVariant(get_integer(var)); + g_variant_unref(var); + } } else if (g_variant_is_of_type(opt->def, G_VARIANT_TYPE("s"))) { GVariant *const var = dec_binding->getter(opt->id); - options_obj[opt->id] = QJsonValue::fromVariant(g_variant_get_string(var, NULL)); - g_variant_unref(var); + if (var != NULL) { + options_obj[opt->id] = QJsonValue::fromVariant(g_variant_get_string(var, NULL)); + g_variant_unref(var); + } }else { continue; } @@ -879,43 +933,31 @@ void StoreSession::load_decoders(dock::ProtocolDock *widget, QJsonArray dec_arra const srd_decoder_option *const opt = (srd_decoder_option*)l->data; if (options_obj.contains(opt->id)) { - if (opt->values) { - QString enum_option = options_obj[opt->id].toString(); - for (GSList *vl = opt->values; vl; vl = vl->next) { - GVariant *const var = (GVariant*)vl->data; - assert(var); - if (enum_option == QString::fromUtf8(g_variant_get_string(var, NULL))) { - dec->set_option(opt->id, var); - break; - } - } - } else if (g_variant_is_of_type(opt->def, G_VARIANT_TYPE("d"))) { - double d_option = options_obj[opt->id].toDouble(); - dec->set_option(opt->id, g_variant_new_double(d_option)); + GVariant *new_value = NULL; + if (g_variant_is_of_type(opt->def, G_VARIANT_TYPE("d"))) { + new_value = g_variant_new_double(options_obj[opt->id].toDouble()); } else if (g_variant_is_of_type(opt->def, G_VARIANT_TYPE("x"))) { - int64_t d_option = options_obj[opt->id].toDouble(); - GVariant *new_value = NULL; const GVariantType *const type = g_variant_get_type(opt->def); if (g_variant_type_equal(type, G_VARIANT_TYPE_BYTE)) - new_value = g_variant_new_byte(d_option); + new_value = g_variant_new_byte(options_obj[opt->id].toInt()); else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT16)) - new_value = g_variant_new_int16(d_option); + new_value = g_variant_new_int16(options_obj[opt->id].toInt()); else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT16)) - new_value = g_variant_new_uint16(d_option); + new_value = g_variant_new_uint16(options_obj[opt->id].toInt()); else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT32)) - new_value = g_variant_new_int32(d_option); + new_value = g_variant_new_int32(options_obj[opt->id].toInt()); else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT32)) - new_value = g_variant_new_int32(d_option); + new_value = g_variant_new_uint32(options_obj[opt->id].toInt()); else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT64)) - new_value = g_variant_new_int64(d_option); + new_value = g_variant_new_int64(options_obj[opt->id].toInt()); else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT64)) - new_value = g_variant_new_uint64(d_option); - if (new_value != NULL) - dec->set_option(opt->id, new_value); + new_value = g_variant_new_uint64(options_obj[opt->id].toInt()); } else if (g_variant_is_of_type(opt->def, G_VARIANT_TYPE("s"))) { - QString s_option = options_obj[opt->id].toString(); - dec->set_option(opt->id, g_variant_new_string(s_option.toLocal8Bit().data())); + new_value = g_variant_new_string(options_obj[opt->id].toString().toLocal8Bit().data()); } + + if (new_value != NULL) + dec->set_option(opt->id, new_value); } } dec->commit(); @@ -944,7 +986,7 @@ void StoreSession::load_decoders(dock::ProtocolDock *widget, QJsonArray dec_arra } #endif -double StoreSession::get_double(GVariant *var) +double StoreSession::get_integer(GVariant *var) { double val = 0; const GVariantType *const type = g_variant_get_type(var); @@ -970,4 +1012,5 @@ double StoreSession::get_double(GVariant *var) return val; } + } // pv diff --git a/DSView/pv/storesession.h b/DSView/pv/storesession.h old mode 100644 new mode 100755 index 04911dd68687aab19421cd749bba701a880f072a..6c5687943817cca02d511cb7d64542ba8666c78e --- a/DSView/pv/storesession.h +++ b/DSView/pv/storesession.h @@ -60,7 +60,7 @@ public: const QString& error() const; - bool save_start(); + bool save_start(QString session_file); bool export_start(); @@ -84,7 +84,7 @@ public: private: QList getSuportedExportFormats(); - double get_double(GVariant * var); + double get_integer(GVariant * var); signals: void progress_updated(); diff --git a/DSView/pv/toolbars/filebar.cpp b/DSView/pv/toolbars/filebar.cpp old mode 100644 new mode 100755 index 6b3b8f006e04577d844f80b97fdbbc0990e33fe4..8da52bcbfc62da51fcc397ef4d8e4281e05e1509 --- a/DSView/pv/toolbars/filebar.cpp +++ b/DSView/pv/toolbars/filebar.cpp @@ -1,229 +1,252 @@ -/* - * This file is part of the DSView project. - * DSView is based on PulseView. - * - * Copyright (C) 2013 DreamSourceLab - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include - -#include -#include -#include - -#include "filebar.h" -#include "../device/devinst.h" -#include "../dialogs/dsmessagebox.h" - -#include - -namespace pv { -namespace toolbars { - -FileBar::FileBar(SigSession &session, QWidget *parent) : - QToolBar("File Bar", parent), - _enable(true), - _session(session), - _file_button(this) -{ - setMovable(false); - - _action_load = new QAction(this); - _action_load->setText(QApplication::translate( - "File", "&Load...", 0)); - _action_load->setIcon(QIcon::fromTheme("file", - QIcon(":/icons/open.png"))); - _action_load->setObjectName(QString::fromUtf8("actionLoad")); - connect(_action_load, SIGNAL(triggered()), this, SLOT(on_actionLoad_triggered())); - - _action_store = new QAction(this); - _action_store->setText(QApplication::translate( - "File", "S&tore...", 0)); - _action_store->setIcon(QIcon::fromTheme("file", - QIcon(":/icons/save.png"))); - _action_store->setObjectName(QString::fromUtf8("actionStore")); - connect(_action_store, SIGNAL(triggered()), this, SLOT(on_actionStore_triggered())); - - _action_default = new QAction(this); - _action_default->setText(QApplication::translate( - "File", "&Default...", 0)); - _action_default->setIcon(QIcon::fromTheme("file", - QIcon(":/icons/gear.png"))); - _action_default->setObjectName(QString::fromUtf8("actionDefault")); - connect(_action_default, SIGNAL(triggered()), this, SLOT(on_actionDefault_triggered())); - - _menu_session = new QMenu(tr("Settings"), parent); - _menu_session->setIcon(QIcon::fromTheme("file", - QIcon(":/icons/gear.png"))); - _menu_session->setObjectName(QString::fromUtf8("menuSession")); - _menu_session->addAction(_action_load); - _menu_session->addAction(_action_store); - _menu_session->addAction(_action_default); - - _action_open = new QAction(this); - _action_open->setText(QApplication::translate( - "File", "&Open...", 0)); - _action_open->setIcon(QIcon::fromTheme("file", - QIcon(":/icons/open.png"))); - _action_open->setObjectName(QString::fromUtf8("actionOpen")); - connect(_action_open, SIGNAL(triggered()), this, SLOT(on_actionOpen_triggered())); - - _action_save = new QAction(this); - _action_save->setText(QApplication::translate( - "File", "&Save...", 0)); - _action_save->setIcon(QIcon::fromTheme("file", - QIcon(":/icons/save.png"))); - _action_save->setObjectName(QString::fromUtf8("actionSave")); - connect(_action_save, SIGNAL(triggered()), this, SIGNAL(on_save())); - - _action_export = new QAction(this); - _action_export->setText(QApplication::translate("File", "&Export...", 0)); - _action_export->setIcon(QIcon::fromTheme("file",QIcon(":/icons/export.png"))); - _action_export->setObjectName(QString::fromUtf8("actionExport")); - connect(_action_export, SIGNAL(triggered()), this, SIGNAL(on_export())); - - - _action_capture = new QAction(this); - _action_capture->setText(QApplication::translate( - "File", "&Capture...", 0)); - _action_capture->setIcon(QIcon::fromTheme("file", - QIcon(":/icons/capture.png"))); - _action_capture->setObjectName(QString::fromUtf8("actionCapture")); - connect(_action_capture, SIGNAL(triggered()), this, SLOT(on_actionCapture_triggered())); - - _file_button.setPopupMode(QToolButton::InstantPopup); - _file_button.setIcon(QIcon(":/icons/file.png")); - - _menu = new QMenu(this); - _menu->addMenu(_menu_session); - _menu->addAction(_action_open); - _menu->addAction(_action_save); - _menu->addAction(_action_export); - _menu->addAction(_action_capture); - _file_button.setMenu(_menu); - addWidget(&_file_button); -} - -void FileBar::on_actionOpen_triggered() -{ - const QString DIR_KEY("OpenPath"); - QSettings settings; - // Show the dialog - const QString file_name = QFileDialog::getOpenFileName( - this, tr("Open File"), settings.value(DIR_KEY).toString(), tr( - "DSView Data (*.dsl)")); - if (!file_name.isEmpty()) { - QDir CurrentDir; - settings.setValue(DIR_KEY, CurrentDir.absoluteFilePath(file_name)); - load_file(file_name); - } -} - -void FileBar::session_error( - const QString text, const QString info_text) -{ - QMetaObject::invokeMethod(this, "show_session_error", - Qt::QueuedConnection, Q_ARG(QString, text), - Q_ARG(QString, info_text)); -} - -void FileBar::show_session_error( - const QString text, const QString info_text) -{ - dialogs::DSMessageBox msg(this); - msg.mBox()->setText(text); - msg.mBox()->setInformativeText(info_text); - msg.mBox()->setStandardButtons(QMessageBox::Ok); - msg.mBox()->setIcon(QMessageBox::Warning); - msg.exec(); -} - -void FileBar::on_actionLoad_triggered() -{ - const QString DIR_KEY("SessionLoadPath"); - QSettings settings; - // Show the dialog - const QString file_name = QFileDialog::getOpenFileName( - this, tr("Open Session"), settings.value(DIR_KEY).toString(), tr( - "DSView Session (*.dsc)")); - if (!file_name.isEmpty()) { - QDir CurrentDir; - settings.setValue(DIR_KEY, CurrentDir.absoluteFilePath(file_name)); - load_session(file_name); - } -} - -void FileBar::on_actionDefault_triggered() -{ - QDir dir(DS_RES_PATH); - if (!dir.exists()) { - dialogs::DSMessageBox msg(this); - msg.mBox()->setText(tr("Session Load")); - msg.mBox()->setInformativeText(tr("Cannot find default session file for this device!")); - msg.mBox()->setStandardButtons(QMessageBox::Ok); - msg.mBox()->setIcon(QMessageBox::Warning); - msg.exec(); - return; - } - - QString driver_name = _session.get_device()->name(); - QString mode_name = QString::number(_session.get_device()->dev_inst()->mode); - QString file_name = dir.absolutePath() + "/" + driver_name + mode_name + ".def.dsc"; - if (!file_name.isEmpty()) - load_session(file_name); -} - -void FileBar::on_actionStore_triggered() -{ - const QString DIR_KEY("SessionStorePath"); - QSettings settings; - QString file_name = QFileDialog::getSaveFileName( - this, tr("Save Session"), settings.value(DIR_KEY).toString(), - tr("DSView Session (*.dsc)")); - if (!file_name.isEmpty()) { - QFileInfo f(file_name); - if(f.suffix().compare("dsc")) - file_name.append(tr(".dsc")); - QDir CurrentDir; - settings.setValue(DIR_KEY, CurrentDir.absoluteFilePath(file_name)); - store_session(file_name); - } -} - -void FileBar::on_actionCapture_triggered() -{ - _file_button.close(); - QCoreApplication::sendPostedEvents(); - QTimer::singleShot(100, this, SIGNAL(on_screenShot())); -} - -void FileBar::enable_toggle(bool enable) -{ - _file_button.setDisabled(!enable); - _file_button.setIcon(enable ? QIcon(":/icons/file.png") : - QIcon(":/icons/file_dis.png")); -} - -void FileBar::set_settings_en(bool enable) -{ - _menu_session->setDisabled(!enable); -} - -} // namespace toolbars -} // namespace pv +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2013 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include +#include +#include + +#include "filebar.h" +#include "../device/devinst.h" +#include "../dialogs/dsmessagebox.h" + +#include + +namespace pv { +namespace toolbars { + +FileBar::FileBar(SigSession &session, QWidget *parent) : + QToolBar("File Bar", parent), + _enable(true), + _session(session), + _file_button(this) +{ + setMovable(false); + setContentsMargins(0,0,0,0); + setIconSize(QSize(40, 28)); + + _action_load = new QAction(this); + _action_load->setObjectName(QString::fromUtf8("actionLoad")); + connect(_action_load, SIGNAL(triggered()), this, SLOT(on_actionLoad_triggered())); + + _action_store = new QAction(this); + _action_store->setObjectName(QString::fromUtf8("actionStore")); + connect(_action_store, SIGNAL(triggered()), this, SLOT(on_actionStore_triggered())); + + _action_default = new QAction(this); + _action_default->setObjectName(QString::fromUtf8("actionDefault")); + connect(_action_default, SIGNAL(triggered()), this, SLOT(on_actionDefault_triggered())); + + _menu_session = new QMenu(this); + _menu_session->setObjectName(QString::fromUtf8("menuSession")); + _menu_session->addAction(_action_load); + _menu_session->addAction(_action_store); + _menu_session->addAction(_action_default); + + _action_open = new QAction(this); + _action_open->setObjectName(QString::fromUtf8("actionOpen")); + connect(_action_open, SIGNAL(triggered()), this, SLOT(on_actionOpen_triggered())); + + _action_save = new QAction(this); + _action_save->setObjectName(QString::fromUtf8("actionSave")); + connect(_action_save, SIGNAL(triggered()), this, SIGNAL(on_save())); + + _action_export = new QAction(this); + _action_export->setObjectName(QString::fromUtf8("actionExport")); + connect(_action_export, SIGNAL(triggered()), this, SIGNAL(on_export())); + + + _action_capture = new QAction(this); + _action_capture->setObjectName(QString::fromUtf8("actionCapture")); + connect(_action_capture, SIGNAL(triggered()), this, SLOT(on_actionCapture_triggered())); + + _file_button.setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + _file_button.setPopupMode(QToolButton::InstantPopup); + + _menu = new QMenu(this); + _menu->addMenu(_menu_session); + _menu->addAction(_action_open); + _menu->addAction(_action_save); + _menu->addAction(_action_export); + _menu->addAction(_action_capture); + _file_button.setMenu(_menu); + addWidget(&_file_button); + + retranslateUi(); +} + +void FileBar::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + retranslateUi(); + else if (event->type() == QEvent::StyleChange) + reStyle(); + QToolBar::changeEvent(event); +} + +void FileBar::retranslateUi() +{ + _file_button.setText(tr("File")); + _menu_session->setTitle(tr("Settings")); + _action_load->setText(tr("&Load...")); + _action_store->setText(tr("S&tore...")); + _action_default->setText(tr("&Default...")); + _action_open->setText(tr("&Open...")); + _action_save->setText(tr("&Save...")); + _action_export->setText(tr("&Export...")); + _action_capture->setText(tr("&Capture...")); +} + +void FileBar::reStyle() +{ + QString iconPath = ":/icons/" + qApp->property("Style").toString(); + + _action_load->setIcon(QIcon(iconPath+"/open.png")); + _action_store->setIcon(QIcon(iconPath+"/save.png")); + _action_default->setIcon(QIcon(iconPath+"/gear.png")); + _menu_session->setIcon(QIcon(iconPath+"/gear.png")); + _action_open->setIcon(QIcon(iconPath+"/open.png")); + _action_save->setIcon(QIcon(iconPath+"/save.png")); + _action_export->setIcon(QIcon(iconPath+"/export.png")); + _action_capture->setIcon(QIcon(iconPath+"/capture.png")); + _file_button.setIcon(QIcon(iconPath+"/file.png")); +} + +void FileBar::on_actionOpen_triggered() +{ + const QString DIR_KEY("OpenPath"); + QSettings settings(QApplication::organizationName(), QApplication::applicationName()); + // Show the dialog + const QString file_name = QFileDialog::getOpenFileName( + this, tr("Open File"), settings.value(DIR_KEY).toString(), tr( + "DSView Data (*.dsl)")); + if (!file_name.isEmpty()) { + QDir CurrentDir; + settings.setValue(DIR_KEY, CurrentDir.absoluteFilePath(file_name)); + load_file(file_name); + } +} + +void FileBar::session_error( + const QString text, const QString info_text) +{ + QMetaObject::invokeMethod(this, "show_session_error", + Qt::QueuedConnection, Q_ARG(QString, text), + Q_ARG(QString, info_text)); +} + +void FileBar::show_session_error( + const QString text, const QString info_text) +{ + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(text); + msg.mBox()->setInformativeText(info_text); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); + msg.exec(); +} + +void FileBar::on_actionLoad_triggered() +{ + const QString DIR_KEY("SessionLoadPath"); + QSettings settings(QApplication::organizationName(), QApplication::applicationName()); + // Show the dialog + const QString file_name = QFileDialog::getOpenFileName( + this, tr("Open Session"), settings.value(DIR_KEY).toString(), tr( + "DSView Session (*.dsc)")); + if (!file_name.isEmpty()) { + QDir CurrentDir; + settings.setValue(DIR_KEY, CurrentDir.absoluteFilePath(file_name)); + load_session(file_name); + } +} + +void FileBar::on_actionDefault_triggered() +{ +#ifdef Q_OS_LINUX + QDir dir(DS_RES_PATH); +#else + QDir dir(QCoreApplication::applicationDirPath()); + assert(dir.cd("res")); +#endif + if (!dir.exists()) { + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Session Load")); + msg.mBox()->setInformativeText(tr("Cannot find default session file for this device!")); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); + msg.exec(); + return; + } + + QString driver_name = _session.get_device()->name(); + QString mode_name = QString::number(_session.get_device()->dev_inst()->mode); + int language = QLocale::English; + GVariant *gvar_tmp = _session.get_device()->get_config(NULL, NULL, SR_CONF_LANGUAGE); + if (gvar_tmp != NULL) { + language = g_variant_get_int16(gvar_tmp); + g_variant_unref(gvar_tmp); + } + QString file_name = dir.absolutePath() + "/" + driver_name + mode_name + + ".def"+QString::number(language)+".dsc"; + if (!file_name.isEmpty()) + load_session(file_name); +} + +void FileBar::on_actionStore_triggered() +{ + const QString DIR_KEY("SessionStorePath"); + QSettings settings(QApplication::organizationName(), QApplication::applicationName()); + QString file_name = QFileDialog::getSaveFileName( + this, tr("Save Session"), settings.value(DIR_KEY).toString(), + tr("DSView Session (*.dsc)")); + if (!file_name.isEmpty()) { + QFileInfo f(file_name); + if(f.suffix().compare("dsc")) + file_name.append(tr(".dsc")); + QDir CurrentDir; + settings.setValue(DIR_KEY, CurrentDir.absoluteFilePath(file_name)); + store_session(file_name); + } +} + +void FileBar::on_actionCapture_triggered() +{ + _file_button.close(); + QCoreApplication::sendPostedEvents(); + QTimer::singleShot(100, this, SIGNAL(on_screenShot())); +} + +void FileBar::enable_toggle(bool enable) +{ + _file_button.setDisabled(!enable); +} + +void FileBar::set_settings_en(bool enable) +{ + _menu_session->setDisabled(!enable); +} + +} // namespace toolbars +} // namespace pv diff --git a/DSView/pv/toolbars/filebar.h b/DSView/pv/toolbars/filebar.h old mode 100644 new mode 100755 index 0d85b578b23b5d21a0a1f98389cfc218090e4f6c..3696fab55dfb928aaccc4c3b5d1e2512e32f2065 --- a/DSView/pv/toolbars/filebar.h +++ b/DSView/pv/toolbars/filebar.h @@ -1,91 +1,94 @@ -/* - * This file is part of the DSView project. - * DSView is based on PulseView. - * - * Copyright (C) 2013 DreamSourceLab - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#ifndef DSVIEW_PV_TOOLBARS_FILEBAR_H -#define DSVIEW_PV_TOOLBARS_FILEBAR_H - -#include -#include -#include -#include - -#include "../sigsession.h" - -namespace pv { -namespace toolbars { - -class FileBar : public QToolBar -{ - Q_OBJECT - -public: - explicit FileBar(SigSession &session, QWidget *parent = 0); - - void enable_toggle(bool enable); - - void set_settings_en(bool enable); - -private: - - void session_error( - const QString text, const QString info_text); - void show_session_error( - const QString text, const QString info_text); - -signals: - void load_file(QString); - void on_save(); - void on_export(); - void on_screenShot(); - void load_session(QString); - void store_session(QString); - -private slots: - void on_actionLoad_triggered(); - void on_actionStore_triggered(); - void on_actionDefault_triggered(); - void on_actionOpen_triggered(); - void on_actionCapture_triggered(); - -private: - bool _enable; - SigSession& _session; - - QToolButton _file_button; - - QMenu *_menu; - - QMenu *_menu_session; - QAction *_action_load; - QAction *_action_store; - QAction *_action_default; - - QAction *_action_open; - QAction *_action_save; - QAction *_action_export; - QAction *_action_capture; -}; - -} // namespace toolbars -} // namespace pv - -#endif // DSVIEW_PV_TOOLBARS_FILEBAR_H +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2013 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef DSVIEW_PV_TOOLBARS_FILEBAR_H +#define DSVIEW_PV_TOOLBARS_FILEBAR_H + +#include +#include +#include +#include + +#include "../sigsession.h" + +namespace pv { +namespace toolbars { + +class FileBar : public QToolBar +{ + Q_OBJECT + +public: + explicit FileBar(SigSession &session, QWidget *parent = 0); + + void enable_toggle(bool enable); + + void set_settings_en(bool enable); + +private: + void changeEvent(QEvent *event); + void retranslateUi(); + void reStyle(); + + void session_error( + const QString text, const QString info_text); + void show_session_error( + const QString text, const QString info_text); + +signals: + void load_file(QString); + void on_save(); + void on_export(); + void on_screenShot(); + void load_session(QString); + void store_session(QString); + +private slots: + void on_actionLoad_triggered(); + void on_actionStore_triggered(); + void on_actionDefault_triggered(); + void on_actionOpen_triggered(); + void on_actionCapture_triggered(); + +private: + bool _enable; + SigSession& _session; + + QToolButton _file_button; + + QMenu *_menu; + + QMenu *_menu_session; + QAction *_action_load; + QAction *_action_store; + QAction *_action_default; + + QAction *_action_open; + QAction *_action_save; + QAction *_action_export; + QAction *_action_capture; +}; + +} // namespace toolbars +} // namespace pv + +#endif // DSVIEW_PV_TOOLBARS_FILEBAR_H diff --git a/DSView/pv/toolbars/logobar.cpp b/DSView/pv/toolbars/logobar.cpp old mode 100644 new mode 100755 index a969ede465b6d3762223f6972abbd3212f65e657..45575ca58d9af0ff7f75f06e0ec07a26a68b2c0a --- a/DSView/pv/toolbars/logobar.cpp +++ b/DSView/pv/toolbars/logobar.cpp @@ -1,139 +1,213 @@ -/* - * This file is part of the DSView project. - * DSView is based on PulseView. - * - * Copyright (C) 2013 DreamSourceLab - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include - -#include -#include -#include -#include -#include - -#include "logobar.h" -#include "../dialogs/about.h" -#include "../dialogs/dsmessagebox.h" - -namespace pv { -namespace toolbars { - -LogoBar::LogoBar(SigSession &session, QWidget *parent) : - QToolBar("File Bar", parent), - _enable(true), - _session(session), - _logo_button(this) -{ - setMovable(false); - - _about = new QAction(this); - _about->setText(QApplication::translate( - "File", "&About...", 0)); - _about->setIcon(QIcon::fromTheme("file", - QIcon(":/icons/about.png"))); - _about->setObjectName(QString::fromUtf8("actionAbout")); - _logo_button.addAction(_about); - connect(_about, SIGNAL(triggered()), this, SLOT(on_actionAbout_triggered())); - - _manual = new QAction(this); - _manual->setText(QApplication::translate( - "File", "&Manual", 0)); - _manual->setIcon(QIcon::fromTheme("file", - QIcon(":/icons/manual.png"))); - _manual->setObjectName(QString::fromUtf8("actionManual")); - _logo_button.addAction(_manual); - connect(_manual, SIGNAL(triggered()), this, SLOT(on_actionManual_triggered())); - - _issue = new QAction(this); - _issue->setText(QApplication::translate( - "File", "&Bug Report", 0)); - _issue->setIcon(QIcon::fromTheme("file", - QIcon(":/icons/bug.png"))); - _issue->setObjectName(QString::fromUtf8("actionManual")); - _logo_button.addAction(_issue); - connect(_issue, SIGNAL(triggered()), this, SLOT(on_actionIssue_triggered())); - - _logo_button.setPopupMode(QToolButton::InstantPopup); - _logo_button.setIcon(QIcon(":/icons/logo_noColor.png")); - - QWidget *spacer = new QWidget(this); - spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - addWidget(spacer); - addWidget(&_logo_button); - QWidget *margin = new QWidget(this); - margin->setMinimumWidth(20); - addWidget(margin); -} - -void LogoBar::dsl_connected(bool conn) -{ - if (conn) - _logo_button.setIcon(QIcon(":/icons/logo_color.png")); - else - _logo_button.setIcon(QIcon(":/icons/logo_noColor.png")); -} - -void LogoBar::session_error( - const QString text, const QString info_text) -{ - QMetaObject::invokeMethod(this, "show_session_error", - Qt::QueuedConnection, Q_ARG(QString, text), - Q_ARG(QString, info_text)); -} - -void LogoBar::show_session_error( - const QString text, const QString info_text) -{ - dialogs::DSMessageBox msg(this); - msg.mBox()->setText(text); - msg.mBox()->setInformativeText(info_text); - msg.mBox()->setStandardButtons(QMessageBox::Ok); - msg.mBox()->setIcon(QMessageBox::Warning); - msg.exec(); -} - -void LogoBar::on_actionAbout_triggered() -{ - dialogs::About dlg(this); - dlg.exec(); -} - -void LogoBar::on_actionManual_triggered() -{ - QDir dir(DS_RES_PATH); - dir.cdUp(); - QDesktopServices::openUrl( - QUrl("file:///"+dir.absolutePath() + "/ug.pdf")); -} - -void LogoBar::on_actionIssue_triggered() -{ - QDir dir(QCoreApplication::applicationDirPath()); - QDesktopServices::openUrl( - QUrl(QLatin1String("https://github.com/DreamSourceLab/DSView/issues"))); -} - -void LogoBar::enable_toggle(bool enable) -{ - _logo_button.setDisabled(!enable); -} - -} // namespace toolbars -} // namespace pv +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2013 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "logobar.h" +#include "../dialogs/about.h" +#include "../dialogs/dsmessagebox.h" + +namespace pv { +namespace toolbars { + +LogoBar::LogoBar(SigSession &session, QWidget *parent) : + QToolBar("File Bar", parent), + _enable(true), + _connected(false), + _session(session), + _logo_button(this) +{ + setMovable(false); + setContentsMargins(0,0,0,0); + setIconSize(QSize(40, 28)); + + _action_en = new QAction(this); + _action_en->setObjectName(QString::fromUtf8("actionEn")); + connect(_action_en, SIGNAL(triggered()), this, SLOT(on_actionEn_triggered())); + + _action_cn = new QAction(this); + _action_cn->setObjectName(QString::fromUtf8("actionCn")); + connect(_action_cn, SIGNAL(triggered()), this, SLOT(on_actionCn_triggered())); + + _language = new QMenu(this); + _language->setObjectName(QString::fromUtf8("menuLanguage")); + _language->addAction(_action_cn); + _language->addAction(_action_en); + + _action_en->setIcon(QIcon(":/icons/English.png")); + _action_cn->setIcon(QIcon(":/icons/Chinese.png")); + + _about = new QAction(this); + _about->setObjectName(QString::fromUtf8("actionAbout")); + _logo_button.addAction(_about); + connect(_about, SIGNAL(triggered()), this, SLOT(on_actionAbout_triggered())); + + _manual = new QAction(this); + _manual->setObjectName(QString::fromUtf8("actionManual")); + _logo_button.addAction(_manual); + connect(_manual, SIGNAL(triggered()), this, SIGNAL(openDoc())); + + _issue = new QAction(this); + _issue->setObjectName(QString::fromUtf8("actionManual")); + _logo_button.addAction(_issue); + connect(_issue, SIGNAL(triggered()), this, SLOT(on_actionIssue_triggered())); + + _menu = new QMenu(this); + _menu->addMenu(_language); + _menu->addAction(_about); + _menu->addAction(_manual); + _menu->addAction(_issue); + _logo_button.setMenu(_menu); + + _logo_button.setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + _logo_button.setPopupMode(QToolButton::InstantPopup); + + QWidget *spacer = new QWidget(this); + spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + addWidget(spacer); + addWidget(&_logo_button); + QWidget *margin = new QWidget(this); + margin->setMinimumWidth(20); + addWidget(margin); + + retranslateUi(); +} + +void LogoBar::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + retranslateUi(); + else if (event->type() == QEvent::StyleChange) + reStyle(); + QToolBar::changeEvent(event); +} + +void LogoBar::retranslateUi() +{ + _logo_button.setText(tr("Help")); + _action_en->setText("English"); + _action_cn->setText("中文"); + _language->setTitle(tr("&Language")); + _about->setText(tr("&About...")); + _manual->setText(tr("&Manual")); + _issue->setText(tr("&Bug Report")); + + if (qApp->property("Language") == QLocale::Chinese) + _language->setIcon(QIcon(":/icons/Chinese.png")); + else + _language->setIcon(QIcon(":/icons/English.png")); +} + +void LogoBar::reStyle() +{ + QString iconPath = ":/icons/" + qApp->property("Style").toString(); + + _about->setIcon(QIcon(iconPath+"/about.png")); + _manual->setIcon(QIcon(iconPath+"/manual.png")); + _issue->setIcon(QIcon(iconPath+"/bug.png")); + if (_connected) + _logo_button.setIcon(QIcon(iconPath+"/logo_color.png")); + else + _logo_button.setIcon(QIcon(iconPath+"/logo_noColor.png")); +} + +void LogoBar::dsl_connected(bool conn) +{ + _connected = conn; + QString iconPath = ":/icons/" + qApp->property("Style").toString(); + if (_connected) + _logo_button.setIcon(QIcon(iconPath+"/logo_color.png")); + else + _logo_button.setIcon(QIcon(iconPath+"/logo_noColor.png")); +} + +void LogoBar::session_error( + const QString text, const QString info_text) +{ + QMetaObject::invokeMethod(this, "show_session_error", + Qt::QueuedConnection, Q_ARG(QString, text), + Q_ARG(QString, info_text)); +} + +void LogoBar::show_session_error( + const QString text, const QString info_text) +{ + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(text); + msg.mBox()->setInformativeText(info_text); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); + msg.exec(); +} + +void LogoBar::on_actionEn_triggered() +{ + _language->setIcon(QIcon::fromTheme("file", + QIcon(":/icons/English.png"))); + setLanguage(QLocale::English); +} + +void LogoBar::on_actionCn_triggered() +{ + _language->setIcon(QIcon::fromTheme("file", + QIcon(":/icons/Chinese.png"))); + setLanguage(QLocale::Chinese); +} + +void LogoBar::on_actionAbout_triggered() +{ + dialogs::About dlg(this); + dlg.exec(); +} + +void LogoBar::on_actionManual_triggered() +{ + #ifndef Q_OS_LINUX + QDir dir(QCoreApplication::applicationDirPath()); + #else + QDir dir(DS_RES_PATH); + dir.cdUp(); + #endif + QDesktopServices::openUrl( + QUrl("file:///"+dir.absolutePath() + "/ug.pdf")); +} + +void LogoBar::on_actionIssue_triggered() +{ + QDir dir(QCoreApplication::applicationDirPath()); + QDesktopServices::openUrl( + QUrl(QLatin1String("https://github.com/DreamSourceLab/DSView/issues"))); +} + +void LogoBar::enable_toggle(bool enable) +{ + _logo_button.setDisabled(!enable); +} + +} // namespace toolbars +} // namespace pv diff --git a/DSView/pv/toolbars/logobar.h b/DSView/pv/toolbars/logobar.h old mode 100644 new mode 100755 index d1d2f90581054834bac2c49e18e8badf86acc771..caf686c5a50d143aa400f20bc03028979587d684 --- a/DSView/pv/toolbars/logobar.h +++ b/DSView/pv/toolbars/logobar.h @@ -1,76 +1,91 @@ -/* - * This file is part of the DSView project. - * DSView is based on PulseView. - * - * Copyright (C) 2013 DreamSourceLab - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#ifndef DSVIEW_PV_TOOLBARS_LOGOBAR_H -#define DSVIEW_PV_TOOLBARS_LOGOBAR_H - -#include -#include -#include - -#include "../sigsession.h" - -#include - -namespace pv { -namespace toolbars { - -class LogoBar : public QToolBar -{ - Q_OBJECT - -public: - explicit LogoBar(SigSession &session, QWidget *parent = 0); - - void enable_toggle(bool enable); - - void dsl_connected(bool conn); - -private: - void session_error( - const QString text, const QString info_text); - void show_session_error( - const QString text, const QString info_text); - -signals: - -private slots: - void on_actionAbout_triggered(); - void on_actionManual_triggered(); - void on_actionIssue_triggered(); - -private: - bool _enable; - SigSession& _session; - - QToolButton _logo_button; - - QAction *_about; - QAction *_manual; - QAction *_issue; - -}; - -} // namespace toolbars -} // namespace pv - -#endif // DSVIEW_PV_TOOLBARS_LOGOBAR_H +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2013 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef DSVIEW_PV_TOOLBARS_LOGOBAR_H +#define DSVIEW_PV_TOOLBARS_LOGOBAR_H + +#include +#include +#include +#include + +#include "../sigsession.h" + +#include + +namespace pv { +namespace toolbars { + +class LogoBar : public QToolBar +{ + Q_OBJECT + +public: + explicit LogoBar(SigSession &session, QWidget *parent = 0); + + void enable_toggle(bool enable); + + void dsl_connected(bool conn); + +private: + void changeEvent(QEvent *event); + void retranslateUi(); + void reStyle(); + + void session_error( + const QString text, const QString info_text); + void show_session_error( + const QString text, const QString info_text); + +signals: + void setLanguage(int language); + void openDoc(); + +private slots: + void on_actionEn_triggered(); + void on_actionCn_triggered(); + void on_actionAbout_triggered(); + void on_actionManual_triggered(); + void on_actionIssue_triggered(); + +private: + bool _enable; + bool _connected; + SigSession& _session; + + QToolButton _logo_button; + + QMenu *_menu; + + QMenu *_language; + QAction *_action_en; + QAction *_action_cn; + + QAction *_about; + QAction *_manual; + QAction *_issue; +}; + +} // namespace toolbars +} // namespace pv + +#endif // DSVIEW_PV_TOOLBARS_LOGOBAR_H diff --git a/DSView/pv/toolbars/samplingbar.cpp b/DSView/pv/toolbars/samplingbar.cpp old mode 100644 new mode 100755 index 365244f95debe75116170b186180c169425c11e4..8cebb45b1ac70c2ad0c1ca1292130a5445bd089f --- a/DSView/pv/toolbars/samplingbar.cpp +++ b/DSView/pv/toolbars/samplingbar.cpp @@ -64,21 +64,14 @@ SamplingBar::SamplingBar(SigSession &session, QWidget *parent) : _sample_rate(this), _updating_sample_rate(false), _updating_sample_count(false), - _icon_stop(":/icons/stop.png"), - _icon_start(":/icons/start.png"), - _icon_instant(":/icons/instant.png"), - _icon_start_dis(":/icons/start_dis.png"), - _icon_instant_dis(":/icons/instant_dis.png"), _run_stop_button(this), _instant_button(this), _mode_button(this), - _icon_repeat(":/icons/moder.png"), - _icon_single(":/icons/modes.png"), - _icon_repeat_dis(":/icons/moder_dis.png"), - _icon_single_dis(":/icons/modes_dis.png"), _instant(false) { setMovable(false); + setContentsMargins(0,0,0,0); + setIconSize(QSize(40, 28)); layout()->setMargin(0); layout()->setSpacing(0); @@ -91,20 +84,13 @@ SamplingBar::SamplingBar(SigSession &session, QWidget *parent) : connect(&_instant_button, SIGNAL(clicked()), this, SLOT(on_instant_stop())); - _configure_button.setIcon(QIcon::fromTheme("configure", - QIcon(":/icons/params.png"))); - _mode_button.setPopupMode(QToolButton::InstantPopup); - _mode_button.setIcon(_session.get_run_mode() == pv::SigSession::Single ? _icon_single : _icon_repeat); - _run_stop_button.setIcon(_icon_start); - _instant_button.setIcon(_icon_instant); _device_selector.setSizeAdjustPolicy(QComboBox::AdjustToContents); _sample_rate.setSizeAdjustPolicy(QComboBox::AdjustToContents); _sample_count.setSizeAdjustPolicy(QComboBox::AdjustToContents); _device_selector.setMaximumWidth(ComboBoxMaxWidth); - set_sampling(false); connect(&_sample_count, SIGNAL(currentIndexChanged(int)), this, SLOT(on_samplecount_sel(int))); @@ -117,32 +103,83 @@ SamplingBar::SamplingBar(SigSession &session, QWidget *parent) : QWidget *leftMargin = new QWidget(this); leftMargin->setFixedWidth(4); addWidget(leftMargin); + addWidget(&_device_selector); + _configure_button.setToolButtonStyle(Qt::ToolButtonTextUnderIcon); addWidget(&_configure_button); + addWidget(&_sample_count); addWidget(new QLabel(tr(" @ "))); addWidget(&_sample_rate); _action_single = new QAction(this); - _action_single->setText(QApplication::translate("Sampling", "&Single", 0)); - _action_single->setIcon(QIcon::fromTheme("Sampling", - QIcon(":/icons/oneloop.png"))); connect(_action_single, SIGNAL(triggered()), this, SLOT(on_mode())); _action_repeat = new QAction(this); - _action_repeat->setText(QApplication::translate("Sampling", "&Repetitive", 0)); - _action_repeat->setIcon(QIcon::fromTheme("Sampling", - QIcon(":/icons/repeat.png"))); connect(_action_repeat, SIGNAL(triggered()), this, SLOT(on_mode())); _mode_menu = new QMenu(this); _mode_menu->addAction(_action_single); _mode_menu->addAction(_action_repeat); _mode_button.setMenu(_mode_menu); + + _mode_button.setToolButtonStyle(Qt::ToolButtonTextUnderIcon); _mode_action = addWidget(&_mode_button); + _run_stop_button.setToolButtonStyle(Qt::ToolButtonTextUnderIcon); _run_stop_action = addWidget(&_run_stop_button); + _instant_button.setToolButtonStyle(Qt::ToolButtonTextUnderIcon); _instant_action = addWidget(&_instant_button); + + set_sampling(false); + //retranslateUi(); +} + +void SamplingBar::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + retranslateUi(); + else if (event->type() == QEvent::StyleChange) + reStyle(); + QToolBar::changeEvent(event); +} + +void SamplingBar::retranslateUi() +{ + _configure_button.setText(tr("Options")); + _mode_button.setText(tr("Mode")); + if (_instant) { + if (_session.get_device() && + _session.get_device()->dev_inst()->mode == DSO) + _instant_button.setText(_sampling ? tr("Stop") : tr("Single")); + else + _instant_button.setText(_sampling ? tr("Stop") : tr("Instant")); + _run_stop_button.setText(tr("Start")); + } else { + _run_stop_button.setText(_sampling ? tr("Stop") : tr("Start")); + if (_session.get_device() && + _session.get_device()->dev_inst()->mode == DSO) + _instant_button.setText(tr("Single")); + else + _instant_button.setText(tr("Instant")); + } + + _action_single->setText(tr("&Single")); + _action_repeat->setText(tr("&Repetitive")); +} + +void SamplingBar::reStyle() +{ + QString iconPath = ":/icons/" + qApp->property("Style").toString(); + + _configure_button.setIcon(QIcon(iconPath+"/params.png")); + _mode_button.setIcon(_session.get_run_mode() == pv::SigSession::Single ? QIcon(iconPath+"/modes.png") : + QIcon(iconPath+"/moder.png")); + _run_stop_button.setIcon(_sampling ? QIcon(iconPath+"/stop.png") : + QIcon(iconPath+"/start.png")); + _instant_button.setIcon(QIcon(iconPath+"/instant.png")); + _action_single->setIcon(QIcon(iconPath+"/oneloop.png")); + _action_repeat->setIcon(QIcon(iconPath+"/repeat.png")); } void SamplingBar::set_device_list( @@ -263,9 +300,17 @@ void SamplingBar::zero_adj() if ((dsoSig = dynamic_pointer_cast(s))) dsoSig->set_enable(true); } + const int index_back = _sample_count.currentIndex(); + int i = 0; + for (i = 0; i < _sample_count.count(); i++) + if (_sample_count.itemData(i).value() == ZeroTimeBase) + break; + _sample_count.setCurrentIndex(i); + commit_hori_res(); + run_stop(); - pv::dialogs::WaitingDialog wait(this, get_selected_device()); + pv::dialogs::WaitingDialog wait(this, get_selected_device(), SR_CONF_ZERO); if (wait.start() ==QDialog::Rejected) { BOOST_FOREACH(const boost::shared_ptr s, _session.get_signals()) { @@ -276,6 +321,9 @@ void SamplingBar::zero_adj() if (_session.get_capture_state() == pv::SigSession::Running) on_run_stop(); + + _sample_count.setCurrentIndex(index_back); + commit_hori_res(); } bool SamplingBar::get_sampling() const @@ -292,12 +340,12 @@ void SamplingBar::set_sampling(bool sampling) { lock_guard lock(_sampling_mutex); _sampling = sampling; + QString iconPath = ":/icons/" + qApp->property("Style").toString(); + if (_instant) { - _instant_button.setIcon(sampling ? _icon_stop : _icon_instant); - _run_stop_button.setIcon(sampling ? _icon_start_dis : _icon_start); + _instant_button.setIcon(sampling ? QIcon(iconPath+"/stop.png") : QIcon(iconPath+"/instant.png")); } else { - _run_stop_button.setIcon(sampling ? _icon_stop : _icon_start); - _instant_button.setIcon(sampling ? _icon_instant_dis : _icon_instant); + _run_stop_button.setIcon(sampling ? QIcon(iconPath+"/stop.png") : QIcon(iconPath+"/start.png")); } if (!sampling) { @@ -311,11 +359,12 @@ void SamplingBar::set_sampling(bool sampling) } _mode_button.setEnabled(!sampling); - _mode_button.setIcon(sampling ? (_session.get_run_mode() == pv::SigSession::Single ? _icon_single_dis : _icon_repeat_dis) : - (_session.get_run_mode() == pv::SigSession::Single ? _icon_single : _icon_repeat)); + _mode_button.setIcon(_session.get_run_mode() == pv::SigSession::Single ? QIcon(iconPath+"/modes.png") : + QIcon(iconPath+"/moder.png")); _configure_button.setEnabled(!sampling); - _configure_button.setIcon(sampling ? QIcon(":/icons/params_dis.png") : - QIcon(":/icons/params.png")); + _device_selector.setEnabled(!sampling); + + retranslateUi(); } void SamplingBar::set_sample_rate(uint64_t sample_rate) @@ -679,29 +728,44 @@ double SamplingBar::commit_hori_res() void SamplingBar::commit_settings() { - const double sample_duration = _sample_count.itemData( - _sample_count.currentIndex()).value(); - const uint64_t sample_rate = _sample_rate.itemData( - _sample_rate.currentIndex()).value(); - const uint64_t sample_count = ceil(sample_duration / SR_SEC(1) * - sample_rate); - + bool test = false; const shared_ptr dev_inst = get_selected_device(); - if (dev_inst) { - if (sample_rate != dev_inst->get_sample_rate()) - dev_inst->set_config(NULL, NULL, - SR_CONF_SAMPLERATE, - g_variant_new_uint64(sample_rate)); - if (dev_inst->dev_inst()->mode != DSO) { - if (sample_count != dev_inst->get_sample_limit()) - dev_inst->set_config(NULL, NULL, - SR_CONF_LIMIT_SAMPLES, - g_variant_new_uint64(sample_count)); + if (dev_inst && dev_inst->owner()) { + GVariant *gvar = dev_inst->get_config(NULL, NULL, SR_CONF_TEST); + if (gvar != NULL) { + test = g_variant_get_boolean(gvar); + g_variant_unref(gvar); + } + } + + if (test) { + update_sample_rate_selector_value(); + update_sample_count_selector_value(); + } else { + const double sample_duration = _sample_count.itemData( + _sample_count.currentIndex()).value(); + const uint64_t sample_rate = _sample_rate.itemData( + _sample_rate.currentIndex()).value(); - bool rle_mode = _sample_count.currentText().contains(RLEString); - dev_inst->set_config(NULL, NULL, - SR_CONF_RLE, - g_variant_new_boolean(rle_mode)); + const shared_ptr dev_inst = get_selected_device(); + if (dev_inst) { + if (sample_rate != dev_inst->get_sample_rate()) + dev_inst->set_config(NULL, NULL, + SR_CONF_SAMPLERATE, + g_variant_new_uint64(sample_rate)); + if (dev_inst->dev_inst()->mode != DSO) { + const uint64_t sample_count = ((uint64_t)ceil(sample_duration / SR_SEC(1) * + sample_rate) + 1023ULL) & ~1023ULL; + if (sample_count != dev_inst->get_sample_limit()) + dev_inst->set_config(NULL, NULL, + SR_CONF_LIMIT_SAMPLES, + g_variant_new_uint64(sample_count)); + + bool rle_mode = _sample_count.currentText().contains(RLEString); + dev_inst->set_config(NULL, NULL, + SR_CONF_RLE, + g_variant_new_boolean(rle_mode)); + } } } } @@ -816,6 +880,7 @@ void SamplingBar::on_device_selected() return; _session.stop_capture(); + _session.session_save(); const shared_ptr dev_inst = get_selected_device(); if (!dev_inst) @@ -875,14 +940,13 @@ void SamplingBar::show_session_error( void SamplingBar::reload() { + QString iconPath = ":/icons/" + qApp->property("Style").toString(); if (_session.get_device()->dev_inst()->mode == LOGIC) { - _icon_instant = QIcon(":/icons/instant.png"); - _icon_instant_dis = QIcon(":/icons/instant_dis.png"); - _instant_button.setIcon(_icon_instant); if (_session.get_device()->name() == "virtual-session") { _mode_action->setVisible(false); } else { - _mode_button.setIcon(_session.get_run_mode() == pv::SigSession::Single ? _icon_single : _icon_repeat); + _mode_button.setIcon(_session.get_run_mode() == pv::SigSession::Single ? QIcon(iconPath+"/modes.png") : + QIcon(iconPath+"/moder.png")); _mode_action->setVisible(true); } _run_stop_action->setVisible(true); @@ -894,25 +958,24 @@ void SamplingBar::reload() _instant_action->setVisible(false); enable_toggle(true); } else if (_session.get_device()->dev_inst()->mode == DSO) { - _icon_instant = QIcon(":/icons/single.png"); - _icon_instant_dis = QIcon(":/icons/single_dis.png"); - _instant_button.setIcon(_icon_instant); _mode_action->setVisible(false); _run_stop_action->setVisible(true); _instant_action->setVisible(true); enable_toggle(true); } + retranslateUi(); update(); } void SamplingBar::on_mode() { + QString iconPath = ":/icons/" + qApp->property("Style").toString(); QAction *act = qobject_cast(sender()); if (act == _action_single) { - _mode_button.setIcon(_icon_single); + _mode_button.setIcon(QIcon(iconPath+"/modes.png")); _session.set_run_mode(pv::SigSession::Single); } else if (act == _action_repeat) { - _mode_button.setIcon(_icon_repeat); + _mode_button.setIcon(QIcon(iconPath+"/moder.png")); pv::dialogs::Interval interval_dlg(_session, this); interval_dlg.exec(); _session.set_run_mode(pv::SigSession::Repetitive); diff --git a/DSView/pv/toolbars/samplingbar.h b/DSView/pv/toolbars/samplingbar.h old mode 100644 new mode 100755 index 2aebbce43904f68948a0e7cb4523c04ad711712d..b1bd9b31b01ceb84dd5d9b887c821e640fc3717a --- a/DSView/pv/toolbars/samplingbar.h +++ b/DSView/pv/toolbars/samplingbar.h @@ -61,12 +61,13 @@ class SamplingBar : public QToolBar private: static const int ComboBoxMaxWidth = 200; - static const int RefreshShort = 200; + static const int RefreshShort = 500; static const uint64_t LogicMaxSWDepth64 = SR_GB(16); static const uint64_t LogicMaxSWDepth32 = SR_GB(8); static const uint64_t AnalogMaxSWDepth = SR_Mn(100); static const QString RLEString; static const QString DIVString; + static const uint64_t ZeroTimeBase = SR_US(10); public: SamplingBar(SigSession &session, QWidget *parent); @@ -105,6 +106,10 @@ signals: void hide_calibration(); private: + void changeEvent(QEvent *event); + void retranslateUi(); + void reStyle(); + void update_sample_rate_selector_value(); void update_sample_count_selector(); void update_sample_count_selector_value(); @@ -146,11 +151,6 @@ private: bool _updating_sample_rate; bool _updating_sample_count; - QIcon _icon_stop; - QIcon _icon_start; - QIcon _icon_instant; - QIcon _icon_start_dis; - QIcon _icon_instant_dis; QToolButton _run_stop_button; QToolButton _instant_button; QAction* _run_stop_action; @@ -162,11 +162,6 @@ private: QAction *_action_repeat; QAction *_action_single; - QIcon _icon_repeat; - QIcon _icon_single; - QIcon _icon_repeat_dis; - QIcon _icon_single_dis; - bool _instant; }; diff --git a/DSView/pv/toolbars/titlebar.cpp b/DSView/pv/toolbars/titlebar.cpp old mode 100644 new mode 100755 index 066c3dd41d3df767bc62cd95dccd5083d30218b4..121f7cb9890412d244c2fa57a4a7fb79aff4660a --- a/DSView/pv/toolbars/titlebar.cpp +++ b/DSView/pv/toolbars/titlebar.cpp @@ -29,6 +29,8 @@ #include #include #include +#include + namespace pv { namespace toolbars { @@ -40,7 +42,8 @@ TitleBar::TitleBar(bool top, QWidget *parent, bool hasClose) : _hasClose(hasClose) { setObjectName("TitleBar"); - setFixedHeight(28); + setContentsMargins(0,0,0,0); + setFixedHeight(32); _title = new QLabel(this); QHBoxLayout *hbox = new QHBoxLayout(this); @@ -49,12 +52,8 @@ TitleBar::TitleBar(bool top, QWidget *parent, bool hasClose) : if (_isTop) { _minimizeButton = new QToolButton(this); _minimizeButton->setObjectName("MinimizeButton"); - _minimizeButton->setIcon(QIcon::fromTheme("titlebar", - QIcon(":/icons/minimize.png"))); _maximizeButton = new QToolButton(this); _maximizeButton->setObjectName("MaximizeButton"); - _maximizeButton->setIcon(QIcon::fromTheme("titlebar", - QIcon(":/icons/maximize.png"))); hbox->addWidget(_minimizeButton); hbox->addWidget(_maximizeButton); @@ -68,8 +67,6 @@ TitleBar::TitleBar(bool top, QWidget *parent, bool hasClose) : if (_isTop || _hasClose) { _closeButton= new QToolButton(this); _closeButton->setObjectName("CloseButton"); - _closeButton->setIcon(QIcon::fromTheme("titlebar", - QIcon(":/icons/close.png"))); hbox->addWidget(_closeButton); connect(_closeButton, SIGNAL( clicked() ), parent, SLOT(close() ) ); } @@ -81,13 +78,33 @@ TitleBar::TitleBar(bool top, QWidget *parent, bool hasClose) : setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); } -void TitleBar::paintEvent(QPaintEvent *) +void TitleBar::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::StyleChange) + reStyle(); + QWidget::changeEvent(event); +} + +void TitleBar::reStyle() +{ + QString iconPath = ":/icons/" + qApp->property("Style").toString(); + + if (_isTop) { + _minimizeButton->setIcon(QIcon(iconPath+"/minimize.png")); + _maximizeButton->setIcon(QIcon(iconPath+"/maximize.png")); + } + if (_isTop || _hasClose) + _closeButton->setIcon(QIcon(iconPath+"/close.png")); +} + +void TitleBar::paintEvent(QPaintEvent *event) { + QStyleOption o; + o.initFrom(this); QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &o, &p, this); + p.setRenderHint(QPainter::Antialiasing, true); - p.setPen(QColor(48, 47, 47, 255)); - p.setBrush(QColor(48, 47, 47, 255)); - p.drawRect(rect()); const int xgap = 2; const int xstart = 10; @@ -110,6 +127,8 @@ void TitleBar::paintEvent(QPaintEvent *) p.setPen(QPen(QColor(109, 50, 156, 255), 2, Qt::SolidLine)); p.drawLine(xstart + xgap*8, height()*0.50, xstart + xgap*8, height()*0.66); p.drawLine(xstart + xgap*10, height()*0.34, xstart + xgap*10, height()*0.50); + + QWidget::paintEvent(event); } void TitleBar::setTitle(QString title) @@ -129,25 +148,23 @@ QString TitleBar::title() const void TitleBar::showMaxRestore() { + QString iconPath = ":/icons/" + qApp->property("Style").toString(); if (parentWidget()->isMaximized()) { - _maximizeButton->setIcon(QIcon::fromTheme("titlebar", - QIcon(":/icons/maximize.png"))); + _maximizeButton->setIcon(QIcon(iconPath+"/maximize.png")); normalShow(); } else { - _maximizeButton->setIcon(QIcon::fromTheme("titlebar", - QIcon(":/icons/restore.png"))); + _maximizeButton->setIcon(QIcon(iconPath+"/restore.png")); maximizedShow(); } } void TitleBar::setRestoreButton(bool max) { + QString iconPath = ":/icons/" + qApp->property("Style").toString(); if (!max) { - _maximizeButton->setIcon(QIcon::fromTheme("titlebar", - QIcon(":/icons/maximize.png"))); + _maximizeButton->setIcon(QIcon(iconPath+"/maximize.png")); } else { - _maximizeButton->setIcon(QIcon::fromTheme("titlebar", - QIcon(":/icons/restore.png"))); + _maximizeButton->setIcon(QIcon(iconPath+"/restore.png")); } } diff --git a/DSView/pv/toolbars/titlebar.h b/DSView/pv/toolbars/titlebar.h old mode 100644 new mode 100755 index 6004411a641313915ee0a3a2a58267bc4d5a3528..d48878b17c49c50c9f6fc61a04c54bad56e5ce48 --- a/DSView/pv/toolbars/titlebar.h +++ b/DSView/pv/toolbars/titlebar.h @@ -39,6 +39,10 @@ public: QPoint get_startPos() const; QString title() const; +private: + void changeEvent(QEvent *event); + void reStyle(); + signals: void normalShow(); void maximizedShow(); @@ -48,7 +52,7 @@ public slots: void setRestoreButton(bool max); protected: - void paintEvent(QPaintEvent *); + void paintEvent(QPaintEvent *event); void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); diff --git a/DSView/pv/toolbars/trigbar.cpp b/DSView/pv/toolbars/trigbar.cpp old mode 100644 new mode 100755 index fe54f94aacae98621fb108064d27c0ec3e39a304..6e40ba3885910467811415cea15e0a9b7311bb12 --- a/DSView/pv/toolbars/trigbar.cpp +++ b/DSView/pv/toolbars/trigbar.cpp @@ -1,197 +1,309 @@ -/* - * This file is part of the DSView project. - * DSView is based on PulseView. - * - * Copyright (C) 2013 DreamSourceLab - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "trigbar.h" -#include "../sigsession.h" -#include "../device/devinst.h" -#include "../dialogs/fftoptions.h" - -#include - -namespace pv { -namespace toolbars { - -TrigBar::TrigBar(SigSession &session, QWidget *parent) : - QToolBar("Trig Bar", parent), - _session(session), - _enable(true), - _trig_button(this), - _protocol_button(this), - _measure_button(this), - _search_button(this), - _math_button(this) -{ - setMovable(false); - setContentsMargins(0,0,0,0); - - connect(&_trig_button, SIGNAL(clicked()), - this, SLOT(trigger_clicked())); - connect(&_protocol_button, SIGNAL(clicked()), - this, SLOT(protocol_clicked())); - connect(&_measure_button, SIGNAL(clicked()), - this, SLOT(measure_clicked())); - connect(&_search_button, SIGNAL(clicked()), - this, SLOT(search_clicked())); - - _trig_button.setIcon(QIcon::fromTheme("trig", - QIcon(":/icons/trigger.png"))); - _trig_button.setCheckable(true); - _protocol_button.setIcon(QIcon::fromTheme("trig", - QIcon(":/icons/protocol.png"))); -#ifdef ENABLE_DECODE - _protocol_button.setCheckable(true); -#endif - _measure_button.setIcon(QIcon::fromTheme("trig", - QIcon(":/icons/measure.png"))); - _measure_button.setCheckable(true); - _search_button.setIcon(QIcon::fromTheme("trig", - QIcon(":/icons/search-bar.png"))); - _search_button.setCheckable(true); - _math_button.setIcon(QIcon::fromTheme("trig", - QIcon(":/icons/math.png"))); - - _action_fft = new QAction(this); - _action_fft->setText(QApplication::translate( - "Math", "&FFT", 0)); - _action_fft->setIcon(QIcon::fromTheme("Math", - QIcon(":/icons/fft.png"))); - _action_fft->setObjectName(QString::fromUtf8("actionFft")); - connect(_action_fft, SIGNAL(triggered()), this, SLOT(on_actionFft_triggered())); - - _math_menu = new QMenu(this); - _math_menu->setContentsMargins(0,0,0,0); - _math_menu->addAction(_action_fft); - _math_button.setPopupMode(QToolButton::InstantPopup); - _math_button.setMenu(_math_menu); - - _trig_action = addWidget(&_trig_button); - _protocol_action = addWidget(&_protocol_button); - _measure_action = addWidget(&_measure_button); - _search_action = addWidget(&_search_button); - _math_action = addWidget(&_math_button); -} - -void TrigBar::protocol_clicked() -{ - on_protocol(_protocol_button.isChecked()); -} - -void TrigBar::trigger_clicked() -{ - on_trigger(_trig_button.isChecked()); -} - -void TrigBar::update_trig_btn(bool checked) -{ - _trig_button.setChecked(checked); -} - -void TrigBar::measure_clicked() -{ - on_measure(_measure_button.isChecked()); -} - -void TrigBar::search_clicked() -{ - on_search(_search_button.isChecked()); -} - -void TrigBar::enable_toggle(bool enable) -{ - _trig_button.setDisabled(!enable); - _protocol_button.setDisabled(!enable); - _measure_button.setDisabled(!enable); - _search_button.setDisabled(!enable); - _math_button.setDisabled(!enable); - - _trig_button.setIcon(enable ? QIcon::fromTheme("trig", QIcon(":/icons/trigger.png")) : - QIcon::fromTheme("trig", QIcon(":/icons/trigger_dis.png"))); - _protocol_button.setIcon(enable ? QIcon::fromTheme("trig", QIcon(":/icons/protocol.png")) : - QIcon::fromTheme("trig", QIcon(":/icons/protocol_dis.png"))); - _measure_button.setIcon(enable ? QIcon::fromTheme("trig", QIcon(":/icons/measure.png")) : - QIcon::fromTheme("trig", QIcon(":/icons/measure_dis.png"))); - _search_button.setIcon(enable ? QIcon::fromTheme("trig", QIcon(":/icons/search-bar.png")) : - QIcon::fromTheme("trig", QIcon(":/icons/search-bar_dis.png"))); - _math_button.setIcon(enable ? QIcon::fromTheme("trig", QIcon(":/icons/math.png")) : - QIcon::fromTheme("trig", QIcon(":/icons/math_dis.png"))); -} - -void TrigBar::enable_protocol(bool enable) -{ - _protocol_button.setDisabled(!enable); - _protocol_button.setIcon(enable ? QIcon::fromTheme("trig", QIcon(":/icons/protocol.png")) : - QIcon::fromTheme("trig", QIcon(":/icons/protocol_dis.png"))); -} - -void TrigBar::close_all() -{ - if (_trig_button.isChecked()) { - _trig_button.setChecked(false); - on_trigger(false); - } - if (_protocol_button.isChecked()) { - _protocol_button.setChecked(false); - on_protocol(false); - } - if (_measure_button.isChecked()) { - _measure_button.setChecked(false); - on_measure(false); - } - if(_search_button.isChecked()) { - _search_button.setChecked(false); - on_search(false); - } -} - -void TrigBar::reload() -{ - close_all(); - if (_session.get_device()->dev_inst()->mode == LOGIC) { - _trig_action->setVisible(true); - _protocol_action->setVisible(true); - _measure_action->setVisible(true); - _search_action->setVisible(true); - _math_action->setVisible(false); - } else if (_session.get_device()->dev_inst()->mode == ANALOG) { - _trig_action->setVisible(false); - _protocol_action->setVisible(false); - _measure_action->setVisible(true); - _search_action->setVisible(false); - _math_action->setVisible(false); - } else if (_session.get_device()->dev_inst()->mode == DSO) { - _trig_action->setVisible(true); - _protocol_action->setVisible(false); - _measure_action->setVisible(true); - _search_action->setVisible(false); - _math_action->setVisible(true); - } - enable_toggle(true); - update(); -} - -void TrigBar::on_actionFft_triggered() -{ - pv::dialogs::FftOptions fft_dlg(this, _session); - fft_dlg.exec(); -} - -} // namespace toolbars -} // namespace pv +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2013 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "trigbar.h" +#include "../sigsession.h" +#include "../device/devinst.h" +#include "../dialogs/fftoptions.h" +#include "../dialogs/lissajousoptions.h" +#include "../dialogs/mathoptions.h" +#include "../view/trace.h" + +#include +#include +#include + +namespace pv { +namespace toolbars { + +const QString TrigBar::DARK_STYLE = "dark"; +const QString TrigBar::LIGHT_STYLE = "light"; + +TrigBar::TrigBar(SigSession &session, QWidget *parent) : + QToolBar("Trig Bar", parent), + _session(session), + _enable(true), + _trig_button(this), + _protocol_button(this), + _measure_button(this), + _search_button(this), + _function_button(this), + _display_button(this) +{ + setMovable(false); + setContentsMargins(0,0,0,0); + setIconSize(QSize(40, 28)); + + connect(&_trig_button, SIGNAL(clicked()), + this, SLOT(trigger_clicked())); + connect(&_protocol_button, SIGNAL(clicked()), + this, SLOT(protocol_clicked())); + connect(&_measure_button, SIGNAL(clicked()), + this, SLOT(measure_clicked())); + connect(&_search_button, SIGNAL(clicked()), + this, SLOT(search_clicked())); + + _trig_button.setCheckable(true); +#ifdef ENABLE_DECODE + _protocol_button.setCheckable(true); +#endif + _measure_button.setCheckable(true); + _search_button.setCheckable(true); + + _action_fft = new QAction(this); + _action_fft->setObjectName(QString::fromUtf8("actionFft")); + connect(_action_fft, SIGNAL(triggered()), this, SLOT(on_actionFft_triggered())); + + _action_math = new QAction(this); + _action_math->setObjectName(QString::fromUtf8("actionMath")); + connect(_action_math, SIGNAL(triggered()), this, SLOT(on_actionMath_triggered())); + + _function_menu = new QMenu(this); + _function_menu->setContentsMargins(0,0,0,0); + _function_menu->addAction(_action_fft); + _function_menu->addAction(_action_math); + _function_button.setPopupMode(QToolButton::InstantPopup); + _function_button.setMenu(_function_menu); + + _action_lissajous = new QAction(this); + _action_lissajous->setObjectName(QString::fromUtf8("actionLissajous")); + connect(_action_lissajous, SIGNAL(triggered()), this, SLOT(on_actionLissajous_triggered())); + + _dark_style = new QAction(this); + _dark_style->setObjectName(QString::fromUtf8("actionDark")); + connect(_dark_style, SIGNAL(triggered()), this, SLOT(on_actionDark_triggered())); + + _light_style = new QAction(this); + _light_style->setObjectName(QString::fromUtf8("actionLight")); + connect(_light_style, SIGNAL(triggered()), this, SLOT(on_actionLight_triggered())); + + _themes = new QMenu(this); + _themes->setObjectName(QString::fromUtf8("menuThemes")); + _themes->addAction(_light_style); + _themes->addAction(_dark_style); + + _display_menu = new QMenu(this); + _display_menu->setContentsMargins(0,0,0,0); + _display_menu->addMenu(_themes); + _display_menu->addAction(_action_lissajous); + _display_button.setPopupMode(QToolButton::InstantPopup); + _display_button.setMenu(_display_menu); + + _trig_button.setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + _protocol_button.setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + _measure_button.setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + _search_button.setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + _function_button.setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + _display_button.setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + + _protocol_button.setContentsMargins(0,0,0,0); + + _trig_action = addWidget(&_trig_button); + _protocol_action = addWidget(&_protocol_button); + _measure_action = addWidget(&_measure_button); + _search_action = addWidget(&_search_button); + _function_action = addWidget(&_function_button); + _display_action = addWidget(&_display_button); + + retranslateUi(); +} + +void TrigBar::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + retranslateUi(); + else if (event->type() == QEvent::StyleChange) + reStyle(); + QToolBar::changeEvent(event); +} + +void TrigBar::retranslateUi() +{ + _trig_button.setText(tr("Trigger")); + _protocol_button.setText(tr("Decode")); + _measure_button.setText(tr("Measure")); + _search_button.setText(tr("Search")); + _function_button.setText(tr("Function")); + _display_button.setText(tr("Display")); + _themes->setTitle(tr("Themes")); + _dark_style->setText(tr("Dark")); + _light_style->setText(tr("Light")); + _action_lissajous->setText(tr("&Lissajous")); + + _action_fft->setText(tr("FFT")); + _action_math->setText(tr("Math")); +} + +void TrigBar::reStyle() +{ + QString iconPath = ":/icons/" + qApp->property("Style").toString(); + + _trig_button.setIcon(QIcon(iconPath+"/trigger.png")); + _protocol_button.setIcon(QIcon(iconPath+"/protocol.png")); + _measure_button.setIcon(QIcon(iconPath+"/measure.png")); + _search_button.setIcon(QIcon(iconPath+"/search-bar.png")); + _function_button.setIcon(QIcon(iconPath+"/function.png")); + _display_button.setIcon(QIcon(iconPath+"/display.png")); + + _action_fft->setIcon(QIcon(iconPath+"/fft.png")); + _action_math->setIcon(QIcon(iconPath+"/math.png")); + _action_lissajous->setIcon(QIcon(iconPath+"/lissajous.png")); + _dark_style->setIcon(QIcon(iconPath+"/dark.png")); + _light_style->setIcon(QIcon(iconPath+"/light.png")); + _themes->setIcon(QIcon(iconPath+"/"+qApp->property("Style").toString()+".png")); +} + +void TrigBar::protocol_clicked() +{ + on_protocol(_protocol_button.isChecked()); +} + +void TrigBar::trigger_clicked() +{ + on_trigger(_trig_button.isChecked()); +} + +void TrigBar::update_trig_btn(bool checked) +{ + _trig_button.setChecked(checked); +} + +void TrigBar::update_protocol_btn(bool checked) +{ + _protocol_button.setChecked(checked); +} + +void TrigBar::update_measure_btn(bool checked) +{ + _measure_button.setChecked(checked); +} + +void TrigBar::update_search_btn(bool checked) +{ + _search_button.setChecked(checked); +} + +void TrigBar::measure_clicked() +{ + on_measure(_measure_button.isChecked()); +} + +void TrigBar::search_clicked() +{ + on_search(_search_button.isChecked()); +} + +void TrigBar::enable_toggle(bool enable) +{ + _trig_button.setDisabled(!enable); + _protocol_button.setDisabled(!enable); + _measure_button.setDisabled(!enable); + _search_button.setDisabled(!enable); + _function_button.setDisabled(!enable); + _display_button.setDisabled(!enable); +} + +void TrigBar::enable_protocol(bool enable) +{ + _protocol_button.setDisabled(!enable); +} + +void TrigBar::close_all() +{ + if (_trig_button.isChecked()) { + _trig_button.setChecked(false); + on_trigger(false); + } + if (_protocol_button.isChecked()) { + _protocol_button.setChecked(false); + on_protocol(false); + } + if (_measure_button.isChecked()) { + _measure_button.setChecked(false); + on_measure(false); + } + if(_search_button.isChecked()) { + _search_button.setChecked(false); + on_search(false); + } +} + +void TrigBar::reload() +{ + close_all(); + if (_session.get_device()->dev_inst()->mode == LOGIC) { + _trig_action->setVisible(true); + _protocol_action->setVisible(true); + _measure_action->setVisible(true); + _search_action->setVisible(true); + _function_action->setVisible(false); + _action_lissajous->setVisible(false); + } else if (_session.get_device()->dev_inst()->mode == ANALOG) { + _trig_action->setVisible(false); + _protocol_action->setVisible(false); + _measure_action->setVisible(true); + _search_action->setVisible(false); + _function_action->setVisible(false); + _action_lissajous->setVisible(false); + } else if (_session.get_device()->dev_inst()->mode == DSO) { + _trig_action->setVisible(true); + _protocol_action->setVisible(false); + _measure_action->setVisible(true); + _search_action->setVisible(false); + _function_action->setVisible(true); + _action_lissajous->setVisible(true); + } + enable_toggle(true); + update(); +} + +void TrigBar::on_actionFft_triggered() +{ + pv::dialogs::FftOptions fft_dlg(this, _session); + fft_dlg.exec(); +} + +void TrigBar::on_actionMath_triggered() +{ + pv::dialogs::MathOptions math_dlg(_session, this); + math_dlg.exec(); +} + +void TrigBar::on_actionDark_triggered() +{ + setTheme(DARK_STYLE); + _themes->setIcon(QIcon(":/icons/"+DARK_STYLE+"/"+DARK_STYLE+".png")); +} + +void TrigBar::on_actionLight_triggered() +{ + setTheme(LIGHT_STYLE); + _themes->setIcon(QIcon(":/icons/"+LIGHT_STYLE+"/"+LIGHT_STYLE+".png")); +} + +void TrigBar::on_actionLissajous_triggered() +{ + pv::dialogs::LissajousOptions lissajous_dlg(_session, this); + lissajous_dlg.exec(); +} + +} // namespace toolbars +} // namespace pv diff --git a/DSView/pv/toolbars/trigbar.h b/DSView/pv/toolbars/trigbar.h old mode 100644 new mode 100755 index 6c2048b7011e6dd20f2ba3e0c242210292deaa1f..6a86218f7c6c304b81d819754d67d7f4f67270f5 --- a/DSView/pv/toolbars/trigbar.h +++ b/DSView/pv/toolbars/trigbar.h @@ -1,86 +1,115 @@ -/* - * This file is part of the DSView project. - * DSView is based on PulseView. - * - * Copyright (C) 2013 DreamSourceLab - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#ifndef DSVIEW_PV_TOOLBARS_TRIGBAR_H -#define DSVIEW_PV_TOOLBARS_TRIGBAR_H - -#include -#include -#include -#include - -namespace pv { - -class SigSession; - -namespace toolbars { - -class TrigBar : public QToolBar -{ - Q_OBJECT -public: - explicit TrigBar(SigSession &session, QWidget *parent = 0); - - void enable_toggle(bool enable); - void enable_protocol(bool enable); - void close_all(); - void reload(); - -signals: - void on_protocol(bool visible); - void on_trigger(bool visible); - void on_measure(bool visible); - void on_search(bool visible); - -public slots: - void protocol_clicked(); - void trigger_clicked(); - void measure_clicked(); - void search_clicked(); - - void update_trig_btn(bool checked); - - void on_actionFft_triggered(); - -private: - SigSession& _session; - bool _enable; - QToolButton _trig_button; - QToolButton _protocol_button; - QToolButton _measure_button; - QToolButton _search_button; - QToolButton _math_button; - QAction* _trig_action; - QAction* _protocol_action; - QAction* _measure_action; - QAction* _search_action; - QAction* _math_action; - - QMenu* _math_menu; - QAction* _action_fft; - -}; - -} // namespace toolbars -} // namespace pv - -#endif // DSVIEW_PV_TOOLBARS_TRIGBAR_H +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2013 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef DSVIEW_PV_TOOLBARS_TRIGBAR_H +#define DSVIEW_PV_TOOLBARS_TRIGBAR_H + +#include +#include +#include +#include + +namespace pv { + +class SigSession; + +namespace toolbars { + +class TrigBar : public QToolBar +{ + Q_OBJECT + +protected: + static const QString DARK_STYLE; + static const QString LIGHT_STYLE; + +public: + explicit TrigBar(SigSession &session, QWidget *parent = 0); + + void enable_toggle(bool enable); + void enable_protocol(bool enable); + void close_all(); + void reload(); + +private: + void changeEvent(QEvent *event); + void retranslateUi(); + void reStyle(); + +signals: + void setTheme(QString style); + void on_protocol(bool visible); + void on_trigger(bool visible); + void on_measure(bool visible); + void on_search(bool visible); + void show_lissajous(bool visible); + +private slots: + void on_actionDark_triggered(); + void on_actionLight_triggered(); + void on_actionLissajous_triggered(); + +public slots: + void protocol_clicked(); + void trigger_clicked(); + void measure_clicked(); + void search_clicked(); + + void update_trig_btn(bool checked); + void update_protocol_btn(bool checked); + void update_measure_btn(bool checked); + void update_search_btn(bool checked); + + void on_actionFft_triggered(); + void on_actionMath_triggered(); + +private: + SigSession& _session; + bool _enable; + QToolButton _trig_button; + QToolButton _protocol_button; + QToolButton _measure_button; + QToolButton _search_button; + QToolButton _function_button; + QToolButton _display_button; + QAction* _trig_action; + QAction* _protocol_action; + QAction* _measure_action; + QAction* _search_action; + QAction* _function_action; + QAction* _display_action; + + QMenu* _function_menu; + QAction* _action_fft; + QAction* _action_math; + + QMenu* _display_menu; + QMenu *_themes; + QAction *_dark_style; + QAction *_light_style; + QAction* _action_lissajous; +}; + +} // namespace toolbars +} // namespace pv + +#endif // DSVIEW_PV_TOOLBARS_TRIGBAR_H diff --git a/DSView/pv/view/analogsignal.cpp b/DSView/pv/view/analogsignal.cpp old mode 100644 new mode 100755 index d583d9650c7e9ed8e1c35b9e3d34963f88c08a17..692a9f02f3e39c97492b8466ab195c37b29fe95d --- a/DSView/pv/view/analogsignal.cpp +++ b/DSView/pv/view/analogsignal.cpp @@ -54,10 +54,42 @@ AnalogSignal::AnalogSignal(boost::shared_ptr dev_inst, _data(data), _rects(NULL) { - _typeWidth = 3; + _typeWidth = 5; _colour = SignalColours[probe->index % countof(SignalColours)]; - _bits = -1; - _zero_vrate = 0.5; + + GVariant *gvar; + // channel bits + gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_UNIT_BITS); + if (gvar != NULL) { + _bits = g_variant_get_byte(gvar); + g_variant_unref(gvar); + } else { + _bits = DefaultBits; + qDebug("Warning: config_get SR_CONF_UNIT_BITS failed, set to %d(default).", DefaultBits); + } + gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_REF_MIN); + if (gvar != NULL) { + _ref_min = g_variant_get_uint32(gvar); + g_variant_unref(gvar); + } else { + _ref_min = 1; + } + gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_REF_MAX); + if (gvar != NULL) { + _ref_max = g_variant_get_uint32(gvar); + g_variant_unref(gvar); + } else { + _ref_max = ((1 << _bits) - 1); + } + + // -- vpos + gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_PROBE_OFFSET); + if (gvar != NULL) { + _zero_offset = g_variant_get_uint16(gvar); + g_variant_unref(gvar); + } else { + qDebug() << "ERROR: config_get SR_CONF_PROBE_OFFSET failed."; + } } AnalogSignal::AnalogSignal(boost::shared_ptr s, @@ -67,12 +99,13 @@ AnalogSignal::AnalogSignal(boost::shared_ptr s, _data(data), _rects(NULL) { - _typeWidth = 3; + _typeWidth = 5; _bits = s->get_bits(); - _zero_vrate = s->get_zero_vrate(); + _ref_min = s->get_ref_min(); + _ref_max = s->get_ref_max(); + _zero_offset = s->get_zero_offset(); _scale = s->get_scale(); - _hw_offset = s->get_hw_offset(); } AnalogSignal::~AnalogSignal() @@ -88,9 +121,9 @@ boost::shared_ptr AnalogSignal::data() const return _data; } -void AnalogSignal::set_scale(float scale) +void AnalogSignal::set_scale(int height) { - _scale = scale; + _scale = height / (_ref_max - _ref_min); } float AnalogSignal::get_scale() const @@ -103,9 +136,25 @@ int AnalogSignal::get_bits() const return _bits; } +double AnalogSignal::get_ref_min() const +{ + return _ref_min; +} + +double AnalogSignal::get_ref_max() const +{ + return _ref_max; +} + int AnalogSignal::get_hw_offset() const { - return _hw_offset; + int hw_offset = 0; + GVariant *gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_PROBE_HW_OFFSET); + if (gvar != NULL) { + hw_offset = g_variant_get_uint16(gvar); + g_variant_unref(gvar); + } + return hw_offset; } int AnalogSignal::commit_settings() @@ -124,9 +173,9 @@ int AnalogSignal::commit_settings() ret = _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_COUPLING, g_variant_new_byte(_probe->coupling)); - // -- vpos - ret = _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_VPOS, - g_variant_new_double(_probe->vpos)); + // -- offset + ret = _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_OFFSET, + g_variant_new_uint16(_probe->offset)); // -- trig_value _dev_inst->set_config(_probe, NULL, SR_CONF_TRIGGER_VALUE, @@ -160,6 +209,17 @@ uint8_t AnalogSignal::get_acCoupling() const return coupling; } +bool AnalogSignal::get_mapDefault() const +{ + bool isDefault = true; + GVariant* gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_PROBE_MAP_DEFAULT); + if (gvar != NULL) { + isDefault = g_variant_get_boolean(gvar); + g_variant_unref(gvar); + } + return isDefault; +} + QString AnalogSignal::get_mapUnit() const { QString unit; @@ -193,55 +253,80 @@ double AnalogSignal::get_mapMax() const return max; } +uint64_t AnalogSignal::get_factor() const +{ + GVariant* gvar; + uint64_t factor; + gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_PROBE_FACTOR); + if (gvar != NULL) { + factor = g_variant_get_uint64(gvar); + g_variant_unref(gvar); + return factor; + } else { + qDebug() << "ERROR: config_get SR_CONF_PROBE_FACTOR failed."; + return 1; + } +} + +int AnalogSignal::ratio2value(double ratio) const +{ + return ratio * (_ref_max - _ref_min) + _ref_min; +} + +int AnalogSignal::ratio2pos(double ratio) const +{ + const int height = get_totalHeight(); + const int top = get_y() - height * 0.5; + return ratio * height + top; +} + +double AnalogSignal::value2ratio(int value) const +{ + return max(0.0, (value - _ref_min) / (_ref_max - _ref_min)); +} + +double AnalogSignal::pos2ratio(int pos) const +{ + const int height = get_totalHeight(); + const int top = get_y() - height / 2; + return min(max(pos - top, 0), height) * 1.0 / height; +} + /** * **/ void AnalogSignal::set_zero_vpos(int pos) { if (enabled()) { - const int height = get_totalHeight(); - const int top = get_y() - height / 2; - set_zero_vrate(min(max(pos - top, 0), height) * 1.0 / height, false); + set_zero_ratio(pos2ratio(pos)); } } int AnalogSignal::get_zero_vpos() const { - return (_zero_vrate - 0.5) * get_totalHeight() + get_y(); + return ratio2pos(get_zero_ratio()); } -void AnalogSignal::set_zero_vrate(double rate, bool force_update) +void AnalogSignal::set_zero_ratio(double ratio) { if (_view->session().get_capture_state() == SigSession::Running) return; - _zero_vrate = rate; - update_vpos(); - - if (force_update) - update_offset(); + _zero_offset = ratio2value(ratio); + _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_OFFSET, + g_variant_new_uint16(_zero_offset)); } -double AnalogSignal::get_zero_vrate() const +double AnalogSignal::get_zero_ratio() const { - return _zero_vrate; + return value2ratio(_zero_offset); } -void AnalogSignal::update_vpos() +int AnalogSignal::get_zero_offset() const { - double vpos_off = (0.5 - _zero_vrate) * get_vdiv() * DS_CONF_DSO_VDIVS; - _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_VPOS, - g_variant_new_double(vpos_off)); + return _zero_offset; } -void AnalogSignal::update_offset() -{ - if (_dev_inst->name().contains("virtual") || - _dev_inst->name() == "DSLogic") - _hw_offset = (1 << _bits) * 0.5; - else - _hw_offset = _zero_vrate * ((1 << _bits) - 1); -} /** * Event **/ @@ -256,7 +341,7 @@ void AnalogSignal::resize() /** * Paint **/ -void AnalogSignal::paint_back(QPainter &p, int left, int right) +void AnalogSignal::paint_back(QPainter &p, int left, int right, QColor fore, QColor back) { assert(_view); @@ -268,14 +353,14 @@ void AnalogSignal::paint_back(QPainter &p, int left, int right) const double mapSteps = (get_mapMax() - get_mapMin()) / DIVS; const QString mapUnit = get_mapUnit(); - QPen solidPen(Signal::dsFore); + QPen solidPen(fore); solidPen.setStyle(Qt::SolidLine); p.setPen(solidPen); - p.setBrush(Trace::dsBack); + p.setBrush(back); // paint rule double y = get_y() - height * 0.5; - double mapValue = get_mapMax() + (_zero_vrate - 0.5) * (get_mapMax() - get_mapMin()); + double mapValue = get_mapMax() + (get_zero_ratio() - 0.5) * (get_mapMax() - get_mapMin()); for (i = 0; i < DIVS; i++) { p.drawLine(left, y, left+10, y); if (i == 0 || i == DIVS/2) @@ -305,16 +390,20 @@ void AnalogSignal::paint_back(QPainter &p, int left, int right) QString::number(mapValue,'f',2)+mapUnit); } -void AnalogSignal::paint_mid(QPainter &p, int left, int right) +void AnalogSignal::paint_mid(QPainter &p, int left, int right, QColor fore, QColor back) { + (void)fore; + (void)back; + assert(_data); assert(_view); assert(right >= left); const int height = get_totalHeight(); - const int top = get_y() - height * 0.5; - const int bottom = get_y() + height * 0.5; - const float zeroY = _zero_vrate * height + top; + const float top = get_y() - height * 0.5; + const float bottom = get_y() + height * 0.5; + const float zeroY = ratio2pos(get_zero_ratio()); + const int width = right - left + 1; const double scale = _view->scale(); assert(scale > 0); @@ -334,52 +423,19 @@ void AnalogSignal::paint_mid(QPainter &p, int left, int right) if (order == -1) return; - if (_bits != snapshot->get_unit_bytes()*8) { - _bits = snapshot->get_unit_bytes()*8; - _scale = _totalHeight * 1.0f / ((1 << _bits) - 1); - update_offset(); - } const double pixels_offset = offset; const double samplerate = _data->samplerate(); const int64_t cur_sample_count = snapshot->get_sample_count(); const double samples_per_pixel = samplerate * scale; const uint64_t ring_start = snapshot->get_ring_start(); -// int64_t start_pixel; -// uint64_t start_index; -// int64_t start_skew_pixels; - //const double first_pos = (_view->session().cur_samplelimits() - cur_sample_count) / samples_per_pixel; - // const double start_sample = (snapshot->get_ring_start() + - // (pixels_offset + left - first_pos) * samples_per_pixel); - //start_pixel = floor(first_pos - pixels_offset - left); - // if (start_sample < 0) { - // start_index = 0; - // start_skew_pixels = 0; - // } else { - // start_index = (uint64_t)(start_sample) % cur_sample_count; - // start_skew_pixels = (start_sample - floor(start_sample)) / samples_per_pixel; - // } - // if (start_pixel < left) - // start_pixel = left; - // start_pixel -= start_skew_pixels; - // int64_t show_length = ceil(samples_per_pixel*(right - start_pixel + 1)); - int64_t start_pixel; uint64_t start_index; - const double over_pixel = cur_sample_count / samples_per_pixel - - pixels_offset - right; - if (over_pixel <= left - right) { - return; - } else if (over_pixel <= 0) { - start_index = ring_start; - start_pixel = over_pixel + right - left; - } else { - const double over_sample = over_pixel * samples_per_pixel; - start_index = (uint64_t)(ring_start + floor(over_sample)) % cur_sample_count; - start_pixel = right + (over_sample - floor(over_sample)) / samples_per_pixel; - } + const double index_offset = pixels_offset * samples_per_pixel; + start_index = (uint64_t)(ring_start + floor(index_offset)) % cur_sample_count; + start_pixel = (floor(index_offset) - index_offset) / samples_per_pixel ; - int64_t show_length = ceil(samples_per_pixel*(start_pixel + 1)); + int64_t show_length = min(floor(cur_sample_count - floor(index_offset)), ceil(width*samples_per_pixel + 1)); if (show_length <= 0) return; @@ -387,12 +443,12 @@ void AnalogSignal::paint_mid(QPainter &p, int left, int right) paint_trace(p, snapshot, zeroY, start_pixel, start_index, show_length, samples_per_pixel, order, - top, bottom, right-left); + top, bottom, width); else paint_envelope(p, snapshot, zeroY, start_pixel, start_index, show_length, samples_per_pixel, order, - top, bottom, right-left); + top, bottom, width); } void AnalogSignal::paint_trace(QPainter &p, @@ -400,7 +456,7 @@ void AnalogSignal::paint_trace(QPainter &p, int zeroY, const int start_pixel, const uint64_t start_index, const int64_t sample_count, const double samples_per_pixel, const int order, - const int top, const int bottom, const int width) + const float top, const float bottom, const int width) { (void)width; @@ -413,28 +469,26 @@ void AnalogSignal::paint_trace(QPainter &p, p.setPen(_colour); //p.setPen(QPen(_colour, 2, Qt::SolidLine)); - QPointF *points = new QPointF[sample_count + 2]; + QPointF *points = new QPointF[sample_count]; QPointF *point = points; uint64_t yindex = start_index; - int x = 0; -// const int64_t start_offset = start_pixel - (int64_t)(start_index / samples_per_pixel + 0.5); - //for (int64_t sample = 0; x < right; sample++) { - const int64_t start_offset = start_pixel + (int64_t)(start_index / samples_per_pixel + 0.5); - for (int64_t sample = 0; x >= 0; sample++) { - x = start_offset - (start_index + sample) / samples_per_pixel - 0.5; + + const int hw_offset = get_hw_offset(); + float x = start_pixel; + double pixels_per_sample = 1.0/samples_per_pixel; + for (int64_t sample = 0; sample < sample_count; sample++) { uint64_t index = (yindex * channel_num + order) * unit_bytes; - double yvalue = samples[index]; + float yvalue = samples[index]; for(uint8_t i = 1; i < unit_bytes; i++) yvalue += (samples[++index] << i*8); - yvalue = zeroY + ((int)yvalue - _hw_offset) * _scale; - yvalue = min(max((int)yvalue, top), bottom); + yvalue = zeroY + (yvalue - hw_offset) * _scale; + yvalue = min(max(yvalue, top), bottom); *point++ = QPointF(x, yvalue); - if (sample != 0 && yindex == snapshot->get_ring_end()) { - *point++ = QPointF(0, points[sample].y()); + if (yindex == snapshot->get_ring_end()) break; - } yindex++; yindex %= snapshot->get_sample_count(); + x += pixels_per_sample; } p.drawPolyline(points, point - points); delete[] points; @@ -446,7 +500,7 @@ void AnalogSignal::paint_envelope(QPainter &p, int zeroY, const int start_pixel, const uint64_t start_index, const int64_t sample_count, const double samples_per_pixel, const int order, - const int top, const int bottom, const int width) + const float top, const float bottom, const int width) { using namespace Qt; using pv::data::AnalogSnapshot; @@ -458,38 +512,32 @@ void AnalogSignal::paint_envelope(QPainter &p, return; p.setPen(QPen(NoPen)); - //p.setPen(QPen(_colour, 2, Qt::SolidLine)); p.setBrush(_colour); if (!_rects) - _rects = new QRectF[width+3]; + _rects = new QRectF[width+10]; QRectF *rect = _rects; int px = -1, pre_px; - int y_min = zeroY, y_max = zeroY, pre_y_min = zeroY, pre_y_max = zeroY; + float y_min = zeroY, y_max = zeroY, pre_y_min = zeroY, pre_y_max = zeroY; int pcnt = 0; - const double scale_samples_pre_pixel = samples_per_pixel / e.scale; + const double scale_pixels_per_samples = e.scale / samples_per_pixel; const uint64_t ring_end = max((int64_t)0, (int64_t)snapshot->get_ring_end() / e.scale - 1); -// const int64_t start_offset = start_pixel - -// (int64_t)(e.start / scale_samples_pre_pixel + 0.5); -// for(uint64_t sample = 0; sample < e.length; sample++) { - const int64_t start_offset = start_pixel + - (int64_t)(e.start / scale_samples_pre_pixel + 0.5); + const int hw_offset = get_hw_offset(); + + float x = start_pixel; for(uint64_t sample = 0; sample < e.length; sample++) { const uint64_t ring_index = (e.start + sample) % (_view->session().cur_samplelimits() / e.scale); if (sample != 0 && ring_index == ring_end) break; -// const int x = start_offset + -// (e.start + sample) / scale_samples_pre_pixel + 0.5; - const int x = start_offset - - (e.start + sample) / scale_samples_pre_pixel - 0.5; + const AnalogSnapshot::EnvelopeSample *const ev = e.samples + ((e.start + sample) % e.samples_num); - const int b = min(max((int)(zeroY + (ev->max - _hw_offset) * _scale + 0.5), top), bottom); - const int t = min(max((int)(zeroY + (ev->min - _hw_offset) * _scale + 0.5), top), bottom); + const float b = min(max((float)(zeroY + (ev->max - hw_offset) * _scale + 0.5), top), bottom); + const float t = min(max((float)(zeroY + (ev->min - hw_offset) * _scale + 0.5), top), bottom); pre_px = px; - if(px != x) { + if(px != floor(x)) { if (pre_px != -1) { // We overlap this sample with the previous so that vertical // gaps do not appear during steep rising or falling edges @@ -514,6 +562,7 @@ void AnalogSignal::paint_envelope(QPainter &p, y_max = max(b, y_max); y_min = min(t, y_min); } + x += scale_pixels_per_samples; } p.drawRects(_rects, pcnt); diff --git a/DSView/pv/view/analogsignal.h b/DSView/pv/view/analogsignal.h old mode 100644 new mode 100755 index 82689bdc9df16266b257900d3130988190e433d5..b8185764c09d2f5fbdb176da3273ab276b95ba89 --- a/DSView/pv/view/analogsignal.h +++ b/DSView/pv/view/analogsignal.h @@ -39,12 +39,17 @@ namespace view { class AnalogSignal : public Signal { + Q_OBJECT + private: static const QColor SignalColours[4]; static const float EnvelopeThreshold; static const int NumSpanY = 5; static const int NumMiniSpanY = 5; static const int NumSpanX = 10; + + static const uint8_t DefaultBits = 8; + public: AnalogSignal(boost::shared_ptr dev_inst, boost::shared_ptr data, @@ -57,9 +62,11 @@ public: boost::shared_ptr data() const; - void set_scale(float scale); + void set_scale(int height); float get_scale() const; int get_bits() const; + double get_ref_min() const; + double get_ref_max() const; int get_hw_offset() const; int commit_settings(); @@ -68,19 +75,28 @@ public: **/ uint64_t get_vdiv() const; uint8_t get_acCoupling() const; + bool get_mapDefault() const; QString get_mapUnit() const; double get_mapMin() const; double get_mapMax() const; + uint64_t get_factor() const; /** * **/ void set_zero_vpos(int pos); int get_zero_vpos() const; - void set_zero_vrate(double rate, bool force_update); - double get_zero_vrate() const; - void update_vpos(); - void update_offset(); + void set_zero_ratio(double ratio); + double get_zero_ratio() const; + int get_zero_offset() const; + + /** + * + */ + int ratio2value(double ratio) const; + int ratio2pos(double ratio) const; + double value2ratio(int value) const; + double pos2ratio(int pos) const; /** * Event @@ -93,7 +109,7 @@ public: * @param left the x-coordinate of the left edge of the signal * @param right the x-coordinate of the right edge of the signal **/ - void paint_back(QPainter &p, int left, int right); + void paint_back(QPainter &p, int left, int right, QColor fore, QColor back); /** * Paints the signal with a QPainter @@ -101,7 +117,7 @@ public: * @param left the x-coordinate of the left edge of the signal. * @param right the x-coordinate of the right edge of the signal. **/ - void paint_mid(QPainter &p, int left, int right); + void paint_mid(QPainter &p, int left, int right, QColor fore, QColor back); private: void paint_trace(QPainter &p, @@ -109,14 +125,14 @@ private: int zeroY, const int start_pixel, const uint64_t start_index, const int64_t sample_count, const double samples_per_pixel, const int order, - const int top, const int bottom, const int width); + const float top, const float bottom, const int width); void paint_envelope(QPainter &p, const boost::shared_ptr &snapshot, int zeroY, const int start_pixel, const uint64_t start_index, const int64_t sample_count, const double samples_per_pixel, const int order, - const int top, const int bottom, const int width); + const float top, const float bottom, const int width); private: boost::shared_ptr _data; @@ -125,8 +141,10 @@ private: float _scale; double _zero_vrate; - int _hw_offset; + int _zero_offset; int _bits; + double _ref_min; + double _ref_max; }; } // namespace view diff --git a/DSView/pv/view/cursor.cpp b/DSView/pv/view/cursor.cpp old mode 100644 new mode 100755 index 4f96b1aac819181b6370ea3f35dce0fdf9a4f21a..c4818d64eedb374aebe3b3bb22205c12f6dce7c8 --- a/DSView/pv/view/cursor.cpp +++ b/DSView/pv/view/cursor.cpp @@ -102,7 +102,7 @@ void Cursor::paint_label(QPainter &p, const QRect &rect, if (close.contains(QPoint(_view.hover_point().x(), _view.hover_point().y()))) p.setBrush(Ruler::CursorColor[(index - 1) % 8]); else if (r.contains(QPoint(_view.hover_point().x(), _view.hover_point().y()))) - p.setBrush(Ruler::HitColor); + p.setBrush(View::Orange); else p.setBrush(Ruler::CursorColor[(index - 1) % 8]); p.drawRect(r); @@ -115,9 +115,9 @@ void Cursor::paint_label(QPainter &p, const QRect &rect, p.drawPolygon(points, countof(points)); if (close.contains(QPoint(_view.hover_point().x(), _view.hover_point().y()))) - p.setBrush(Ruler::WarnColor); + p.setBrush(View::Red); else - p.setBrush(Ruler::HitColor); + p.setBrush(View::Orange); p.drawRect(close); p.setPen(Qt::black); p.drawLine(close.left() + 2, close.top() + 2, close.right() - 2, close.bottom() - 2); diff --git a/DSView/pv/view/cursor.h b/DSView/pv/view/cursor.h old mode 100644 new mode 100755 diff --git a/DSView/pv/view/decodetrace.cpp b/DSView/pv/view/decodetrace.cpp old mode 100644 new mode 100755 index 28f812ebd5ff464ed78505bc5edee9ecfc2fe7fb..446da53f187054e2af78ceba9b477a7f6ead7471 --- a/DSView/pv/view/decodetrace.cpp +++ b/DSView/pv/view/decodetrace.cpp @@ -170,9 +170,13 @@ void DecodeTrace::set_view(pv::view::View *view) Trace::set_view(view); } -void DecodeTrace::paint_back(QPainter &p, int left, int right) +void DecodeTrace::paint_back(QPainter &p, int left, int right, QColor fore, QColor back) { - QPen pen(Signal::dsGray); + (void)back; + + QColor backFore = fore; + backFore.setAlpha(View::BackAlpha); + QPen pen(backFore); pen.setStyle(Qt::DotLine); p.setPen(pen); const double sigY = get_y() - (_totalHeight - _view->get_signalHeight())*0.5; @@ -184,7 +188,7 @@ void DecodeTrace::paint_back(QPainter &p, int left, int right) const double endX = _decode_end/samples_per_pixel - _view->offset(); const double regionY = get_y() - _totalHeight*0.5 - ControlRectWidth; - p.setBrush(Signal::dsBlue); + p.setBrush(View::Blue); p.drawLine(startX, regionY, startX, regionY + _totalHeight + ControlRectWidth); p.drawLine(endX, regionY, endX, regionY + _totalHeight + ControlRectWidth); const QPointF start_points[] = { @@ -232,12 +236,12 @@ void DecodeTrace::paint_back(QPainter &p, int left, int right) // p.drawText(r.translated(dx, dy), f, h); // Draw the text - p.setPen(DARK_FORE); + p.setPen(fore); p.drawText(r, f, h); } } -void DecodeTrace::paint_mid(QPainter &p, int left, int right) +void DecodeTrace::paint_mid(QPainter &p, int left, int right, QColor fore, QColor back) { using namespace pv::data::decode; @@ -246,7 +250,6 @@ void DecodeTrace::paint_mid(QPainter &p, int left, int right) if (!err.isEmpty()) { draw_error(p, err, left, right); - //return; } const double scale = _view->scale(); @@ -312,10 +315,10 @@ void DecodeTrace::paint_mid(QPainter &p, int left, int right) draw_annotation(a, p, get_text_colour(), annotation_height, left, right, samples_per_pixel, pixels_offset, y, - 0, min_annWidth); + 0, min_annWidth, fore, back); } } else { - draw_nodetail(p, annotation_height, left, right, y, 0); + draw_nodetail(p, annotation_height, left, right, y, 0, fore, back); } y += annotation_height; _cur_row_headings.push_back(row.title()); @@ -323,20 +326,22 @@ void DecodeTrace::paint_mid(QPainter &p, int left, int right) } } } else { - draw_unshown_row(p, y, annotation_height, left, right, tr("Unshown")); + draw_unshown_row(p, y, annotation_height, left, right, tr("Unshown"), fore, back); y += annotation_height; _cur_row_headings.push_back(dec->decoder()->name); } } } -void DecodeTrace::paint_fore(QPainter &p, int left, int right) +void DecodeTrace::paint_fore(QPainter &p, int left, int right, QColor fore, QColor back) { using namespace pv::data::decode; (void)p; (void)left; (void)right; + (void)fore; + (void)back; } bool DecodeTrace::create_popup() @@ -483,7 +488,7 @@ void DecodeTrace::populate_popup_form(QWidget *parent, QFormLayout *form) void DecodeTrace::draw_annotation(const pv::data::decode::Annotation &a, QPainter &p, QColor text_color, int h, int left, int right, double samples_per_pixel, double pixels_offset, int y, - size_t base_colour, double min_annWidth) const + size_t base_colour, double min_annWidth, QColor fore, QColor back) const { const double start = max(a.start_sample() / samples_per_pixel - pixels_offset, (double)left); @@ -498,7 +503,7 @@ void DecodeTrace::draw_annotation(const pv::data::decode::Annotation &a, return; if (_decoder_stack->get_mark_index() == (int64_t)(a.start_sample()+ a.end_sample())/2) { - p.setPen(Signal::dsBlue); + p.setPen(View::Blue); int xpos = (start+end)/2; int ypos = get_y()+_totalHeight*0.5 + 1; const QPoint triangle[] = { @@ -520,7 +525,7 @@ void DecodeTrace::draw_annotation(const pv::data::decode::Annotation &a, start, y, min_annWidth); else { draw_range(a, p, fill, outline, text_color, h, - start, end, y); + start, end, y, fore, back); if ((a.type()/100 == 2) && (end - start > 20)) { BOOST_FOREACH(boost::shared_ptr dec, _decoder_stack->stack()) { @@ -545,16 +550,18 @@ void DecodeTrace::draw_annotation(const pv::data::decode::Annotation &a, void DecodeTrace::draw_nodetail(QPainter &p, int h, int left, int right, int y, - size_t base_colour) const + size_t base_colour, QColor fore, QColor back) const { (void)base_colour; + (void)back; + const QRectF nodetail_rect(left, y - h/2 + 0.5, right - left, h); QString info = tr("Zoom in for details"); int info_left = nodetail_rect.center().x() - p.boundingRect(QRectF(), 0, info).width(); int info_right = nodetail_rect.center().x() + p.boundingRect(QRectF(), 0, info).width(); int height = p.boundingRect(QRectF(), 0, info).height(); - p.setPen(Trace::DARK_FORE); + p.setPen(fore); p.drawLine(left, y, info_left, y); p.drawLine(info_right, y, right, y); p.drawLine(info_left, y, info_left+5, y - height/2 + 0.5); @@ -562,13 +569,15 @@ void DecodeTrace::draw_nodetail(QPainter &p, p.drawLine(info_right, y, info_right-5, y - height/2 + 0.5); p.drawLine(info_right, y, info_right-5, y + height/2 + 0.5); - p.setPen(Trace::DARK_FORE); + p.setPen(fore); p.drawText(nodetail_rect, Qt::AlignCenter | Qt::AlignVCenter, info); } void DecodeTrace::draw_instant(const pv::data::decode::Annotation &a, QPainter &p, QColor fill, QColor outline, QColor text_color, int h, double x, int y, double min_annWidth) const { + (void)outline; + const QString text = a.annotations().empty() ? QString() : a.annotations().back(); // const double w = min((double)p.boundingRect(QRectF(), 0, text).width(), @@ -576,7 +585,8 @@ void DecodeTrace::draw_instant(const pv::data::decode::Annotation &a, QPainter & const double w = min(min_annWidth, (double)h); const QRectF rect(x - w / 2, y - h / 2, w, h); - p.setPen(outline); + //p.setPen(outline); + p.setPen(QPen(Qt::NoPen)); p.setBrush(fill); p.drawRoundedRect(rect, h / 2, h / 2); @@ -589,8 +599,10 @@ void DecodeTrace::draw_instant(const pv::data::decode::Annotation &a, QPainter & void DecodeTrace::draw_range(const pv::data::decode::Annotation &a, QPainter &p, QColor fill, QColor outline, QColor text_color, int h, double start, - double end, int y) const + double end, int y, QColor fore, QColor back) const { + (void)fore; + const double top = y + .5 - h / 2; const double bottom = y + .5 + h / 2; const vector annotations = a.annotations(); @@ -616,7 +628,7 @@ void DecodeTrace::draw_range(const pv::data::decode::Annotation &a, QPainter &p, QPointF(start + cap_width, bottom) }; - p.setPen(DARK_BACK); + p.setPen(back); p.drawConvexPolygon(pts, countof(pts)); if (annotations.empty()) @@ -646,8 +658,8 @@ void DecodeTrace::draw_range(const pv::data::decode::Annotation &a, QPainter &p, QFont font=p.font(); font.setPointSize(DefaultFontSize); p.setFont(font); - p.drawText(rect, Qt::AlignCenter, p.fontMetrics().elidedText( - best_annotation, Qt::ElideRight, rect.width())); + p.drawText(rect, Qt::AlignCenter, p.fontMetrics().elidedText( + best_annotation, Qt::ElideRight, rect.width())); } void DecodeTrace::draw_error(QPainter &p, const QString &message, @@ -670,14 +682,16 @@ void DecodeTrace::draw_error(QPainter &p, const QString &message, } void DecodeTrace::draw_unshown_row(QPainter &p, int y, int h, int left, - int right, QString info) + int right, QString info, QColor fore, QColor back) { + (void)back; + const QRectF unshown_rect(left, y - h/2 + 0.5, right - left, h); int info_left = unshown_rect.center().x() - p.boundingRect(QRectF(), 0, info).width(); int info_right = unshown_rect.center().x() + p.boundingRect(QRectF(), 0, info).width(); int height = p.boundingRect(QRectF(), 0, info).height(); - p.setPen(Trace::DARK_FORE); + p.setPen(fore); p.drawLine(left, y, info_left, y); p.drawLine(info_right, y, right, y); p.drawLine(info_left, y, info_left+5, y - height/2 + 0.5); @@ -685,7 +699,7 @@ void DecodeTrace::draw_unshown_row(QPainter &p, int y, int h, int left, p.drawLine(info_right, y, info_right-5, y - height/2 + 0.5); p.drawLine(info_right, y, info_right-5, y + height/2 + 0.5); - p.setPen(Trace::DARK_FORE); + p.setPen(fore); p.drawText(unshown_rect, Qt::AlignCenter | Qt::AlignVCenter, info); } @@ -700,18 +714,12 @@ void DecodeTrace::create_decoder_form( const srd_decoder *const decoder = dec->decoder(); assert(decoder); - pv::widgets::DecoderGroupBox *const group = - new pv::widgets::DecoderGroupBox(decoder_stack, dec, parent); - connect(group, SIGNAL(del_stack(boost::shared_ptr&)), - this, SLOT(on_del_stack(boost::shared_ptr&))); - QFormLayout *const decoder_form = new QFormLayout(); decoder_form->setContentsMargins(0,0,0,0); decoder_form->setVerticalSpacing(5); decoder_form->setFormAlignment(Qt::AlignLeft); decoder_form->setLabelAlignment(Qt::AlignLeft); decoder_form->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); - group->add_layout(decoder_form); // Add the mandatory channels for(l = decoder->channels; l; l = l->next) { @@ -750,6 +758,12 @@ void DecodeTrace::create_decoder_form( _bindings.push_back(binding); + // + pv::widgets::DecoderGroupBox *const group = + new pv::widgets::DecoderGroupBox(decoder_stack, dec, decoder_form, parent); + connect(group, SIGNAL(del_stack(boost::shared_ptr&)), + this, SLOT(on_del_stack(boost::shared_ptr&))); + form->addRow(group); _decoder_forms.push_back(group); } @@ -916,7 +930,7 @@ int DecodeTrace::rows_size() return size == 0 ? 1 : size; } -void DecodeTrace::paint_type_options(QPainter &p, int right, const QPoint pt) +void DecodeTrace::paint_type_options(QPainter &p, int right, const QPoint pt, QColor fore) { (void)pt; @@ -924,7 +938,7 @@ void DecodeTrace::paint_type_options(QPainter &p, int right, const QPoint pt) const QRectF group_index_rect = get_rect(CHNLREG, y, right); QString index_string; int last_index; - p.setPen(QPen(DARK_FORE, 1, Qt::DashLine)); + p.setPen(QPen(fore, 1, Qt::DashLine)); p.drawLine(group_index_rect.bottomLeft(), group_index_rect.bottomRight()); std::list::iterator i = _index_list.begin(); last_index = (*i); @@ -938,7 +952,7 @@ void DecodeTrace::paint_type_options(QPainter &p, int right, const QPoint pt) index_string = QString::number((*i)) + "," + index_string; last_index = (*i); } - p.setPen(DARK_FORE); + p.setPen(fore); p.drawText(group_index_rect, Qt::AlignRight | Qt::AlignVCenter, index_string); } diff --git a/DSView/pv/view/decodetrace.h b/DSView/pv/view/decodetrace.h old mode 100644 new mode 100755 index bf93e440d6d0d5d8cd2f573edbbd6690431de620..1fcb1257aab29c373d3b8bf4595d2245a2b67833 --- a/DSView/pv/view/decodetrace.h +++ b/DSView/pv/view/decodetrace.h @@ -114,7 +114,7 @@ public: * @param left the x-coordinate of the left edge of the signal. * @param right the x-coordinate of the right edge of the signal. **/ - void paint_back(QPainter &p, int left, int right); + void paint_back(QPainter &p, int left, int right, QColor fore, QColor back); /** * Paints the mid-layer of the trace with a QPainter @@ -122,7 +122,7 @@ public: * @param left the x-coordinate of the left edge of the signal * @param right the x-coordinate of the right edge of the signal **/ - void paint_mid(QPainter &p, int left, int right); + void paint_mid(QPainter &p, int left, int right, QColor fore, QColor back); /** * Paints the foreground layer of the trace with a QPainter @@ -130,7 +130,7 @@ public: * @param left the x-coordinate of the left edge of the signal * @param right the x-coordinate of the right edge of the signal **/ - void paint_fore(QPainter &p, int left, int right); + void paint_fore(QPainter &p, int left, int right, QColor fore, QColor back); bool create_popup(); @@ -146,34 +146,34 @@ public: int get_progress() const; protected: - void paint_type_options(QPainter &p, int right, const QPoint pt); + void paint_type_options(QPainter &p, int right, const QPoint pt, QColor fore); private: void create_popup_form(); void populate_popup_form(QWidget *parent, QFormLayout *form); - void draw_annotation(const pv::data::decode::Annotation &a, QPainter &p, - QColor text_colour, int text_height, int left, int right, - double samples_per_pixel, double pixels_offset, int y, - size_t base_colour, double min_annWidth) const; + void draw_annotation(const pv::data::decode::Annotation &a, QPainter &p, + QColor text_colour, int text_height, int left, int right, + double samples_per_pixel, double pixels_offset, int y, + size_t base_colour, double min_annWidth, QColor fore, QColor back) const; void draw_nodetail(QPainter &p, int text_height, int left, int right, int y, - size_t base_colour) const; + size_t base_colour, QColor fore, QColor back) const; void draw_instant(const pv::data::decode::Annotation &a, QPainter &p, QColor fill, QColor outline, QColor text_color, int h, double x, int y, double min_annWidth) const; - void draw_range(const pv::data::decode::Annotation &a, QPainter &p, - QColor fill, QColor outline, QColor text_color, int h, double start, - double end, int y) const; + void draw_range(const pv::data::decode::Annotation &a, QPainter &p, + QColor fill, QColor outline, QColor text_color, int h, double start, + double end, int y, QColor fore, QColor back) const; void draw_error(QPainter &p, const QString &message, int left, int right); void draw_unshown_row(QPainter &p, int y, int h, int left, - int right, QString info); + int right, QString info, QColor fore, QColor back); void create_decoder_form(boost::shared_ptr &decoder_stack, boost::shared_ptr &dec, diff --git a/DSView/pv/view/devmode.cpp b/DSView/pv/view/devmode.cpp old mode 100644 new mode 100755 index fba98016a77b936494a2c39114f101f0c458d537..8b18d1478bcb018d1c254ea130ebc7bb386fc5e9 --- a/DSView/pv/view/devmode.cpp +++ b/DSView/pv/view/devmode.cpp @@ -24,6 +24,7 @@ #include "trace.h" #include "../sigsession.h" #include "../device/devinst.h" +#include "../device/file.h" #include @@ -44,51 +45,97 @@ namespace view { DevMode::DevMode(QWidget *parent, SigSession &session) : QWidget(parent), - _session(session), - _layout(new QGridLayout(this)) + _session(session) { - _layout->setMargin(5); + _layout = new QHBoxLayout(this); + _layout->setMargin(0); _layout->setSpacing(0); + _layout->setContentsMargins(2, 0, 0, 0); + + _close_button = new QToolButton(this); + _close_button->setObjectName("FileCloseButton"); + _close_button->setContentsMargins(0, 0, 0, 0); + _close_button->setFixedWidth(10); + _close_button->setFixedHeight(height()); + _close_button->setIconSize(QSize(10, 10)); + _close_button->setToolButtonStyle(Qt::ToolButtonIconOnly); + + _pop_menu = new QMenu(this); + + _mode_btn = new QToolButton(this); + _mode_btn->setObjectName("ModeButton"); + _mode_btn->setIconSize(QSize(48, 48)); + _mode_btn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + _mode_btn->setContentsMargins(0, 0, 1000, 0); + _mode_btn->setMenu(_pop_menu); + _mode_btn->setPopupMode(QToolButton::InstantPopup); + _mode_btn->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum); + + _layout->addWidget(_close_button); + _layout->addWidget(_mode_btn); + //_layout->addWidget(new QWidget(this)); + _layout->setStretch(1, 100); setLayout(_layout); } + +void DevMode::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + set_device(); + else if (event->type() == QEvent::StyleChange) + set_device(); + QWidget::changeEvent(event); +} + void DevMode::set_device() { - int index = 0; const boost::shared_ptr dev_inst = _session.get_device(); - assert(dev_inst); - for(std::map::const_iterator i = _mode_button_list.begin(); - i != _mode_button_list.end(); i++) { + for(std::map::const_iterator i = _mode_list.begin(); + i != _mode_list.end(); i++) { (*i).first->setParent(NULL); - _layout->removeWidget((*i).first); + _pop_menu->removeAction((*i).first); delete (*i).first; } - _mode_button_list.clear(); + _mode_list.clear(); + _close_button->setIcon(QIcon()); + _close_button->setDisabled(true); + disconnect(_close_button, SIGNAL(clicked()), this, SLOT(on_close())); + QString iconPath = ":/icons/" + qApp->property("Style").toString(); for (const GSList *l = dev_inst->get_dev_mode_list(); l; l = l->next) { const sr_dev_mode *mode = (const sr_dev_mode *)l->data; + QString icon_name = "/" + QString::fromLocal8Bit(mode->icon); + + QAction *action = new QAction(this); + action->setIcon(QIcon(iconPath+icon_name)); + if (qApp->property("Language") == QLocale::Chinese) + action->setText(mode->name_cn); + else + action->setText(mode->name); + connect(action, SIGNAL(triggered()), this, SLOT(on_mode_change())); + + _mode_list[action] = mode; + if (dev_inst->dev_inst()->mode == _mode_list[action]->mode) { + _mode_btn->setIcon(QIcon(iconPath+icon_name)); + if (qApp->property("Language") == QLocale::Chinese) + _mode_btn->setText(mode->name_cn); + else + _mode_btn->setText(mode->name); + } + _pop_menu->addAction(action); + } - QPushButton *mode_button = new QPushButton(this); - //mode_button->setFlat(true); - mode_button->setMinimumWidth(32); - mode_button->setText(mode->name); - mode_button->setCheckable(true); - - _mode_button_list[mode_button] = mode; - if (dev_inst->dev_inst()->mode == _mode_button_list[mode_button]->mode) - mode_button->setChecked(true); - - connect(mode_button, SIGNAL(clicked()), this, SLOT(on_mode_change())); - - _layout->addWidget(mode_button, index / GRID_COLS, index % GRID_COLS); - //layout->addWidget(new QWidget(), index / GRID_COLS, GRID_COLS); - _layout->setColumnStretch(GRID_COLS, 1); - index++; - } + boost::shared_ptr file_dev; + if((file_dev = dynamic_pointer_cast(dev_inst))) { + _close_button->setDisabled(false); + _close_button->setIcon(QIcon(iconPath+"/close.png")); + connect(_close_button, SIGNAL(clicked()), this, SLOT(on_close())); + } update(); } @@ -106,14 +153,14 @@ void DevMode::on_mode_change() { const boost::shared_ptr dev_inst = _session.get_device(); assert(dev_inst); - QPushButton *button = qobject_cast(sender()); - button->setChecked(true); - if (dev_inst->dev_inst()->mode == _mode_button_list[button]->mode) + QAction *action = qobject_cast(sender()); + if (dev_inst->dev_inst()->mode == _mode_list[action]->mode) return; - for(std::map::const_iterator i = _mode_button_list.begin(); - i != _mode_button_list.end(); i++) { - if ((*i).first == button) { + QString iconPath = ":/icons/" + qApp->property("Style").toString(); + for(std::map::const_iterator i = _mode_list.begin(); + i != _mode_list.end(); i++) { + if ((*i).first == action) { if (dev_inst->dev_inst()->mode != (*i).second->mode) { _session.set_run_mode(SigSession::Single); _session.set_repeating(false); @@ -123,15 +170,28 @@ void DevMode::on_mode_change() dev_inst->set_config(NULL, NULL, SR_CONF_DEVICE_MODE, g_variant_new_int16((*i).second->mode)); - mode_changed(); - button->setChecked(true); + + QString icon_name = "/" + QString::fromLocal8Bit((*i).second->icon); + _mode_btn->setIcon(QIcon(iconPath+icon_name)); + if (qApp->property("Language") == QLocale::Chinese) + _mode_btn->setText((*i).second->name_cn); + else + _mode_btn->setText((*i).second->name); + dev_changed(false); } - } else { - (*i).first->setChecked(false); } } } +void DevMode::on_close() +{ + const boost::shared_ptr dev_inst = _session.get_device(); + assert(dev_inst); + + _session.close_file(dev_inst); + dev_changed(true); +} + void DevMode::mousePressEvent(QMouseEvent *event) { assert(event); diff --git a/DSView/pv/view/devmode.h b/DSView/pv/view/devmode.h old mode 100644 new mode 100755 index fac83c345f6d474470fade038d1556ec07edc937..999f1df00bb1e7e9dd4d84631d547b34fb3d8e3e --- a/DSView/pv/view/devmode.h +++ b/DSView/pv/view/devmode.h @@ -33,8 +33,10 @@ #include #include -#include +#include #include +#include +#include #include @@ -67,21 +69,27 @@ private: void mouseMoveEvent(QMouseEvent *event); void leaveEvent(QEvent *event); + void changeEvent(QEvent *event); + public slots: void set_device(); void on_mode_change(); + void on_close(); private slots: signals: - void mode_changed(); + void dev_changed(bool close); private: SigSession &_session; - QGridLayout * _layout; - std::map _mode_button_list; + QHBoxLayout * _layout; + std::map _mode_list; + QToolButton *_mode_btn; + QMenu *_pop_menu; QPoint _mouse_point; + QToolButton *_close_button; }; } // namespace view diff --git a/DSView/pv/view/dsldial.cpp b/DSView/pv/view/dsldial.cpp old mode 100644 new mode 100755 index 31e9eb8b0508721c649399dda979ff032a20b1ae..f20c872c587e6ac2ea55b30ebf628b503bb77e24 --- a/DSView/pv/view/dsldial.cpp +++ b/DSView/pv/view/dsldial.cpp @@ -1,166 +1,186 @@ -/* - * This file is part of the DSView project. - * DSView is based on PulseView. - * - * Copyright (C) 2014 DreamSourceLab - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "dsldial.h" - -#include -#include - -namespace pv { -namespace view { - -dslDial::dslDial(const uint64_t div, const uint64_t step, - const QVector value, const QVector unit) -{ - assert(div > 0); - assert(step > 0); - assert((uint64_t)value.count() == div); - assert(unit.count() > 0); - - _div = div; - _step = step; - _value = value; - _unit = unit; - _sel = 0; - _factor = 1; -} - -dslDial::~dslDial() -{ -} - -void dslDial::paint(QPainter &p, QRectF dialRect, QColor dialColor, const QPoint pt) -{ - p.setRenderHint(QPainter::Antialiasing, true); - p.setPen(dialColor); - p.setBrush(dialColor); - - int dialMarginAngle = 15 * 16; - int dialStartAngle = 75 * 16; - int dialSpanAngle = -150 * 16; - - // draw dial arc - p.drawArc(dialRect, dialStartAngle + dialMarginAngle, - dialSpanAngle - dialMarginAngle * 2); - // draw ticks - p.save(); - p.translate(dialRect.center()); - p.rotate(270 - dialStartAngle/16); - // draw pointer - p.rotate(-dialSpanAngle/16.0/(_div-1)*_sel); - p.drawEllipse(-3, -3, 6, 6); - p.drawLine(3, 0, 0, dialRect.width()/2-3); - p.drawLine(-3, 0, 0, dialRect.width()/2-3); - p.rotate(+dialSpanAngle/16.0/(_div-1)*_sel); - for (uint64_t i = 0; i < _div; i++) { - // draw major ticks - p.drawLine(0, dialRect.width()/2+3, 0, dialRect.width()/2+8); - // draw minor ticks - for (uint64_t j = 0; (j < 5) && (i < _div - 1); j++) { - p.drawLine(0, dialRect.width()/2+3, 0, dialRect.width()/2+5); - p.rotate(-dialSpanAngle/16/5.0/(_div-1)); - } - } - p.restore(); - // draw value - uint64_t displayValue = _value[_sel]*_factor; - uint64_t displayIndex = 0; - while(displayValue / _step >= 1) { - displayValue = displayValue / _step; - displayIndex++; - } - QString pText = QString::number(displayValue) + _unit[displayIndex] + tr(" / div"); - QFontMetrics fm(p.font()); - const QRectF valueRect = QRectF(dialRect.left(), dialRect.top()-fm.height()-10, dialRect.width(), fm.height()); - p.drawText(valueRect, Qt::AlignCenter, pText); - - // draw +/- - if (dialRect.contains(pt) && pt.x() > dialRect.center().x()) { - const int arcInc = 12; - const QRectF hoverRect = QRectF(dialRect.left()-arcInc, dialRect.top()-arcInc, - dialRect.width()+arcInc*2, dialRect.height()+arcInc*2); - p.drawArc(hoverRect, dialStartAngle + dialSpanAngle/4, dialSpanAngle/2); - p.save(); - p.translate(hoverRect.center()); - const bool inc = pt.y() > dialRect.center().y(); - if (inc) - p.rotate(270-(dialStartAngle/16 + dialSpanAngle/16/4 + dialSpanAngle/16/2)); - else - p.rotate(270-(dialStartAngle/16 + dialSpanAngle/16/4)); - p.drawLine(0, hoverRect.width()/2, - inc ? 10 : -10, hoverRect.width()/2 + 4); - p.restore(); - } -} - -void dslDial::set_sel(uint64_t sel) -{ - assert(sel < _div); - - _sel = sel; -} - -uint64_t dslDial::get_sel() -{ - return _sel; -} - -bool dslDial::isMin() -{ - if(_sel == 0) - return true; - else - return false; -} - -bool dslDial::isMax() -{ - if(_sel == _div - 1) - return true; - else - return false; -} - -uint64_t dslDial::get_value() -{ - return _value[_sel]; -} - -void dslDial::set_value(uint64_t value) -{ - assert(_value.contains(value)); - _sel = _value.indexOf(value, 0); -} - -void dslDial::set_factor(uint64_t factor) -{ - if (_factor != factor) { - _factor = factor; - } -} - -uint64_t dslDial::get_factor() -{ - return _factor; -} - -} // namespace view -} // namespace pv +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2014 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "dsldial.h" + +#include +#include + +namespace pv { +namespace view { + +dslDial::dslDial(const uint64_t div, const uint64_t step, + const QVector value, const QVector unit) +{ + assert(div > 0); + assert(step > 0); + assert((uint64_t)value.count() == div); + assert(unit.count() > 0); + + _div = div; + _step = step; + _value = value; + _unit = unit; + _sel = 0; + _factor = 1; +} + +dslDial::~dslDial() +{ +} + +void dslDial::paint(QPainter &p, QRectF dialRect, QColor dialColor, const QPoint pt, QString &pText) +{ + p.setPen(dialColor); + p.setBrush(dialColor); + + int dialMarginAngle = 15 * 16; + int dialStartAngle = 75 * 16; + int dialSpanAngle = -150 * 16; + + // draw dial arc + p.drawArc(dialRect, dialStartAngle + dialMarginAngle, + dialSpanAngle - dialMarginAngle * 2); + // draw ticks + p.save(); + p.translate(dialRect.center()); + p.rotate(270 - dialStartAngle/16); + // draw pointer + p.rotate(-dialSpanAngle/16.0/(_div-1)*_sel); + p.drawEllipse(-3, -3, 6, 6); + p.drawLine(3, 0, 0, dialRect.width()/2-3); + p.drawLine(-3, 0, 0, dialRect.width()/2-3); + p.rotate(+dialSpanAngle/16.0/(_div-1)*_sel); + for (uint64_t i = 0; i < _div; i++) { + // draw major ticks + p.drawLine(0, dialRect.width()/2+3, 0, dialRect.width()/2+8); + // draw minor ticks + for (uint64_t j = 0; (j < 5) && (i < _div - 1); j++) { + p.drawLine(0, dialRect.width()/2+3, 0, dialRect.width()/2+5); + p.rotate(-dialSpanAngle/16/5.0/(_div-1)); + } + } + p.restore(); + // draw value + uint64_t displayValue = _value[_sel]*_factor; + uint64_t displayIndex = 0; + while(displayValue / _step >= 1) { + displayValue = displayValue / _step; + displayIndex++; + } + pText = QString::number(displayValue) + _unit[displayIndex] + tr("/div"); +// QFontMetrics fm(p.font()); +// const QRectF valueRect = QRectF(dialRect.left(), dialRect.top()-fm.height()-10, dialRect.width(), fm.height()); +// p.drawText(valueRect, Qt::AlignCenter, pText); + + // draw +/- + if (dialRect.contains(pt) && pt.x() > dialRect.center().x()) { + const int arcInc = 12; + const QRectF hoverRect = QRectF(dialRect.left()-arcInc, dialRect.top()-arcInc, + dialRect.width()+arcInc*2, dialRect.height()+arcInc*2); + p.drawArc(hoverRect, dialStartAngle + dialSpanAngle/4, dialSpanAngle/2); + p.save(); + p.translate(hoverRect.center()); + const bool inc = pt.y() > dialRect.center().y(); + if (inc) + p.rotate(270-(dialStartAngle/16 + dialSpanAngle/16/4 + dialSpanAngle/16/2)); + else + p.rotate(270-(dialStartAngle/16 + dialSpanAngle/16/4)); + p.drawLine(0, hoverRect.width()/2, + inc ? 10 : -10, hoverRect.width()/2 + 4); + p.restore(); + } +} + +void dslDial::set_sel(uint64_t sel) +{ + assert(sel < _div); + + _sel = sel; +} + +uint64_t dslDial::get_sel() const +{ + return _sel; +} + +uint64_t dslDial::get_count() const +{ + return _div; +} + +bool dslDial::isMin() +{ + if(_sel == 0) + return true; + else + return false; +} + +bool dslDial::isMax() +{ + if(_sel == _div - 1) + return true; + else + return false; +} + +uint64_t dslDial::get_min() const +{ + return _value[0]; +} + +uint64_t dslDial::get_max() const +{ + return _value[_div-1]; +} + +uint64_t dslDial::get_value() const +{ + return _value[_sel]; +} + +uint64_t dslDial::get_value(uint64_t i) const +{ + assert(i < _div); + return _value[i]; +} + +void dslDial::set_value(uint64_t value) +{ + assert(_value.contains(value)); + _sel = _value.indexOf(value, 0); +} + +void dslDial::set_factor(uint64_t factor) +{ + if (_factor != factor) { + _factor = factor; + } +} + +uint64_t dslDial::get_factor() const +{ + return _factor; +} + +} // namespace view +} // namespace pv diff --git a/DSView/pv/view/dsldial.h b/DSView/pv/view/dsldial.h old mode 100644 new mode 100755 index 1692ff3f16bb60d7c43c160d57b56c10c0df01b6..973e0e6e823c2cbe477f040c597c30490586dbae --- a/DSView/pv/view/dsldial.h +++ b/DSView/pv/view/dsldial.h @@ -1,77 +1,81 @@ -/* - * This file is part of the DSView project. - * DSView is based on PulseView. - * - * Copyright (C) 2013 DreamSourceLab - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef DSVIEW_PV_VIEW_DSLDIAL_H -#define DSVIEW_PV_VIEW_DSLDIAL_H - -#include -#include - -namespace pv { -namespace view { - -class dslDial : public QObject -{ - //Q_OBJECT - -public: - dslDial(const uint64_t div, const uint64_t step, - const QVector value, const QVector unit); - virtual ~dslDial(); - -public: - /** - * Paints the dial with a QPainter - * @param p the QPainter to paint into. - * @param dialRect the rectangle to draw the dial at. - **/ - void paint(QPainter &p, QRectF dialRect, QColor dialColor, - const QPoint pt); - - // set/get current select - void set_sel(uint64_t sel); - uint64_t get_sel(); - - // boundary detection - bool isMin(); - bool isMax(); - - // get current value - uint64_t get_value(); - void set_value(uint64_t value); - - // set/get factor - void set_factor(uint64_t factor); - uint64_t get_factor(); - -private: - uint64_t _div; - uint64_t _step; - QVector _value; - QVector _unit; - uint64_t _sel; - uint64_t _factor; -}; - -} // namespace view -} // namespace pv - -#endif // DSVIEW_PV_VIEW_DSLDIAL_H +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2013 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef DSVIEW_PV_VIEW_DSLDIAL_H +#define DSVIEW_PV_VIEW_DSLDIAL_H + +#include +#include + +namespace pv { +namespace view { + +class dslDial : public QObject +{ + //Q_OBJECT + +public: + dslDial(const uint64_t div, const uint64_t step, + const QVector value, const QVector unit); + virtual ~dslDial(); + +public: + /** + * Paints the dial with a QPainter + * @param p the QPainter to paint into. + * @param dialRect the rectangle to draw the dial at. + **/ + void paint(QPainter &p, QRectF dialRect, QColor dialColor, + const QPoint pt, QString &pText); + + // set/get current select + void set_sel(uint64_t sel); + uint64_t get_sel() const; + uint64_t get_count() const; + + // boundary detection + bool isMin(); + bool isMax(); + uint64_t get_min() const; + uint64_t get_max() const; + + // get current value + uint64_t get_value() const; + uint64_t get_value(uint64_t i) const; + void set_value(uint64_t value); + + // set/get factor + void set_factor(uint64_t factor); + uint64_t get_factor() const; + +private: + uint64_t _div; + uint64_t _step; + QVector _value; + QVector _unit; + uint64_t _sel; + uint64_t _factor; +}; + +} // namespace view +} // namespace pv + +#endif // DSVIEW_PV_VIEW_DSLDIAL_H diff --git a/DSView/pv/view/dsosignal.cpp b/DSView/pv/view/dsosignal.cpp old mode 100644 new mode 100755 index 951790f3fe3b05b785b9e49a3ecab7b34c18c729..a87647809c11df78c64a433eb538c22922865c7f --- a/DSView/pv/view/dsosignal.cpp +++ b/DSView/pv/view/dsosignal.cpp @@ -42,8 +42,8 @@ namespace pv { namespace view { const QString DsoSignal::vDialUnit[DsoSignal::vDialUnitCount] = { - "mv", - "v", + "mV", + "V", }; const QColor DsoSignal::SignalColours[4] = { @@ -63,15 +63,18 @@ DsoSignal::DsoSignal(boost::shared_ptr dev_inst, _data(data), _scale(0), _en_lock(false), + _show(true), _vDialActive(false), + _mValid(false), + _level_valid(false), _autoV(false), _autoH(false), + _autoV_over(false), + _auto_cnt(0), _hover_en(false), _hover_index(0), _hover_point(QPointF(0, 0)), - _hover_value(0), - _ms_gear_hover(false), - _ms_show_hover(false) + _hover_value(0) { QVector vValue; QVector vUnit; @@ -87,9 +90,10 @@ DsoSignal::DsoSignal(boost::shared_ptr dev_inst, GVariant *gvar; GVariantIter iter; g_variant_iter_init(&iter, gvar_list_vdivs); - while(NULL != (gvar = g_variant_iter_next_value(&iter))) + while(NULL != (gvar = g_variant_iter_next_value(&iter))) { vValue.push_back(g_variant_get_uint64(gvar)); - g_variant_unref(gvar); + g_variant_unref(gvar); + } g_variant_unref(gvar_list_vdivs); g_variant_unref(gvar_list); } @@ -114,27 +118,29 @@ boost::shared_ptr DsoSignal::dso_data() const return _data; } -void DsoSignal::set_viewport(pv::view::Viewport *viewport) +void DsoSignal::set_scale(int height) { - Trace::set_viewport(viewport); + _scale = height / (_ref_max - _ref_min); +} - const double ms_left = get_view_rect().right() - (MS_RectWidth + MS_RectMargin) * (get_index() + 1); - const double ms_top = get_view_rect().top() + 5; - for (int i = DSO_MS_BEGIN; i < DSO_MS_END; i++) - _ms_rect[i] = QRect(ms_left, ms_top + MS_RectHeight * i, MS_RectWidth, MS_RectHeight); - _ms_gear_rect = QRect(ms_left+MS_RectRad, ms_top+MS_RectRad, MS_IconSize, MS_IconSize); - _ms_show_rect = QRect(ms_left+MS_RectWidth-MS_RectRad-MS_IconSize, ms_top+MS_RectRad, MS_IconSize, MS_IconSize); +float DsoSignal::get_scale() +{ + return _scale; +} +uint8_t DsoSignal::get_bits() +{ + return _bits; } -void DsoSignal::set_scale(int height) +double DsoSignal::get_ref_min() const { - _scale = height * 1.0f / (1 << _bits); + return _ref_min; } -float DsoSignal::get_scale() +double DsoSignal::get_ref_max() const { - return _scale; + return _ref_max; } int DsoSignal::get_name_width() const @@ -198,8 +204,11 @@ void DsoSignal::set_vDialActive(bool active) _vDialActive = active; } -bool DsoSignal::go_vDialPre() +bool DsoSignal::go_vDialPre(bool manul) { + if (_autoV && manul) + autoV_end(); + if (enabled() && !_vDial->isMin()) { if (_view->session().get_capture_state() == SigSession::Running) _view->session().refresh(RefreshShort); @@ -209,20 +218,25 @@ bool DsoSignal::go_vDialPre() g_variant_new_uint64(_vDial->get_value())); if (_view->session().get_capture_state() == SigSession::Stopped) _scale *= pre_vdiv/_vDial->get_value(); - update_vpos(); - _view->update_calibration(); + _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_OFFSET, + g_variant_new_uint16(_zero_offset)); + + _view->vDial_updated(); _view->set_update(_viewport, true); _view->update(); return true; } else { - if (_autoV) + if (_autoV && !_autoV_over) autoV_end(); return false; } } -bool DsoSignal::go_vDialNext() +bool DsoSignal::go_vDialNext(bool manul) { + if (_autoV && manul) + autoV_end(); + if (enabled() && !_vDial->isMax()) { if (_view->session().get_capture_state() == SigSession::Running) _view->session().refresh(RefreshShort); @@ -232,13 +246,15 @@ bool DsoSignal::go_vDialNext() g_variant_new_uint64(_vDial->get_value())); if (_view->session().get_capture_state() == SigSession::Stopped) _scale *= pre_vdiv/_vDial->get_value(); - update_vpos(); - _view->update_calibration(); + _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_OFFSET, + g_variant_new_uint16(_zero_offset)); + + _view->vDial_updated(); _view->set_update(_viewport, true); _view->update(); return true; } else { - if (_autoV) + if (_autoV && !_autoV_over) autoV_end(); return false; } @@ -270,6 +286,20 @@ bool DsoSignal::load_settings() if (strncmp(_dev_inst->name().toLocal8Bit(), "virtual", 7)) return false; } + gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_REF_MIN); + if (gvar != NULL) { + _ref_min = g_variant_get_uint32(gvar); + g_variant_unref(gvar); + } else { + _ref_min = 1; + } + gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_REF_MAX); + if (gvar != NULL) { + _ref_max = g_variant_get_uint32(gvar); + g_variant_unref(gvar); + } else { + _ref_max = ((1 << _bits) - 1); + } // -- vdiv uint64_t vdiv; @@ -310,24 +340,20 @@ bool DsoSignal::load_settings() // g_variant_new_byte(_acCoupling)); // -- vpos - double vpos; - gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_PROBE_VPOS); + gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_PROBE_OFFSET); if (gvar != NULL) { - vpos = g_variant_get_double(gvar); + _zero_offset = g_variant_get_uint16(gvar); g_variant_unref(gvar); } else { - qDebug() << "ERROR: config_get SR_CONF_PROBE_VPOS failed."; + qDebug() << "ERROR: config_get SR_CONF_PROBE_OFFSET failed."; return false; } - _zero_vrate = min(max((0.5 - vpos / (_vDial->get_value() * DS_CONF_DSO_VDIVS)), 0.0), 1.0); - if (_dev_inst->name().contains("virtual")) - _hw_offset = _zero_vrate * ((1 << _bits) - 1); // -- trig_value gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_TRIGGER_VALUE); if (gvar != NULL) { _trig_value = g_variant_get_byte(gvar); - _trig_delta = get_trig_vrate() - _zero_vrate; + _trig_delta = get_trig_vrate() - get_zero_ratio(); g_variant_unref(gvar); } else { qDebug() << "ERROR: config_get SR_CONF_TRIGGER_VALUE failed."; @@ -359,10 +385,9 @@ int DsoSignal::commit_settings() ret = _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_COUPLING, g_variant_new_byte(_acCoupling)); - // -- vpos - double vpos_off = (0.5 - (get_zero_vpos() - UpMargin) * 1.0/get_view_rect().height()) * _vDial->get_value() * DS_CONF_DSO_VDIVS; - ret = _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_VPOS, - g_variant_new_double(vpos_off)); + // -- offset + ret = _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_OFFSET, + g_variant_new_uint16(_zero_offset)); // -- trig_value _dev_inst->set_config(_probe, NULL, SR_CONF_TRIGGER_VALUE, @@ -371,6 +396,11 @@ int DsoSignal::commit_settings() return ret; } +dslDial * DsoSignal::get_vDial() const +{ + return _vDial; +} + uint64_t DsoSignal::get_vDialValue() const { return _vDial->get_value(); @@ -395,94 +425,96 @@ void DsoSignal::set_acCoupling(uint8_t coupling) } } -int DsoSignal::get_trig_vpos() const +int DsoSignal::ratio2value(double ratio) const +{ + return ratio * (_ref_max - _ref_min) + _ref_min; +} + +int DsoSignal::ratio2pos(double ratio) const +{ + return ratio * get_view_rect().height() + get_view_rect().top(); +} + +double DsoSignal::value2ratio(int value) const +{ + return max(0.0, (value - _ref_min) / (_ref_max - _ref_min)); +} + +double DsoSignal::pos2ratio(int pos) const { - return get_trig_vrate() * get_view_rect().height() + UpMargin; + return min(max(pos - get_view_rect().top(), 0), get_view_rect().height()) * 1.0 / get_view_rect().height(); } double DsoSignal::get_trig_vrate() const { if (_dev_inst->name() == "DSLogic") - return (_trig_value - (1 << (_bits - 1)))* 1.0 / ((1 << _bits) - 1.0) + _zero_vrate; + return value2ratio(_trig_value - ratio2value(0.5)) + get_zero_ratio(); else - return _trig_value * 1.0 / ((1 << _bits) - 1.0); + return value2ratio(_trig_value); } void DsoSignal::set_trig_vpos(int pos, bool delta_change) { assert(_view); if (enabled()) { - double delta = min(max(pos - UpMargin, 0), get_view_rect().height()) * 1.0 / get_view_rect().height(); - if (_dev_inst->name() == "DSLogic") { - delta = delta - _zero_vrate; - delta = min(delta, 0.5); - delta = max(delta, -0.5); - _trig_value = delta * ((1 << _bits) -1) + (1 << (_bits - 1)); - } else { - _trig_value = delta * ((1 << _bits) -1) + 0.5; - } - int margin = TrigMargin; - _trig_value = std::min(std::max(_trig_value, margin), ((1 << _bits) - margin - 1)); - if (delta_change) - _trig_delta = get_trig_vrate() - _zero_vrate; - _dev_inst->set_config(_probe, NULL, SR_CONF_TRIGGER_VALUE, - g_variant_new_byte(_trig_value)); + set_trig_ratio(pos2ratio(pos), delta_change); } } -void DsoSignal::set_trig_vrate(double rate) +void DsoSignal::set_trig_ratio(double ratio, bool delta_change) { - double delta = rate; + double delta = ratio; if (_dev_inst->name() == "DSLogic") { - delta = delta - _zero_vrate; + delta = delta - get_zero_ratio(); delta = min(delta, 0.5); delta = max(delta, -0.5); - _trig_value = delta * ((1 << _bits) - 1) + (1 << (_bits - 1)); + _trig_value = ratio2value(delta + 0.5); } else { - _trig_value = delta * ((1 << _bits) - 1) + 0.5; + _trig_value = ratio2value(delta); } - _trig_delta = get_trig_vrate() - _zero_vrate; + + int margin = TrigMargin; + _trig_value = std::min(std::max(_trig_value, margin), (ratio2value(1) - margin)); + if (delta_change) + _trig_delta = get_trig_vrate() - get_zero_ratio(); _dev_inst->set_config(_probe, NULL, SR_CONF_TRIGGER_VALUE, g_variant_new_byte(_trig_value)); } int DsoSignal::get_zero_vpos() const { - return _zero_vrate * get_view_rect().height() + UpMargin; + return ratio2pos(get_zero_ratio()); } -double DsoSignal::get_zero_vrate() +double DsoSignal::get_zero_ratio() const { - return _zero_vrate; + return value2ratio(_zero_offset); } -double DsoSignal::get_hw_offset() +int DsoSignal::get_hw_offset() const { - return _hw_offset; + int hw_offset = 0; + GVariant *gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_PROBE_HW_OFFSET); + if (gvar != NULL) { + hw_offset = g_variant_get_uint16(gvar); + g_variant_unref(gvar); + } + return hw_offset; } void DsoSignal::set_zero_vpos(int pos) { if (enabled()) { - double delta = _trig_delta* get_view_rect().height(); - set_zero_vrate(min(max(pos - UpMargin, 0), get_view_rect().height()) * 1.0 / get_view_rect().height(), false); - set_trig_vpos(get_zero_vpos() + delta, false); + set_zero_ratio(pos2ratio(pos)); + set_trig_ratio(_trig_delta + get_zero_ratio(), false); } } -void DsoSignal::set_zero_vrate(double rate, bool force_update) +void DsoSignal::set_zero_ratio(double ratio) { - _zero_vrate = rate; - update_vpos(); - - if (!_dev_inst->name().contains("virtual") && - (force_update || - _view->session().get_capture_state() == SigSession::Running)) { - if (_dev_inst->name() == "DSLogic") - _hw_offset = 0x80; - else - _hw_offset = _zero_vrate * ((1 << _bits) - 1); - } + _zero_offset = ratio2value(ratio); + _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_OFFSET, + g_variant_new_uint16(_zero_offset)); } void DsoSignal::set_factor(uint64_t factor) @@ -523,65 +555,132 @@ uint64_t DsoSignal::get_factor() } } -void DsoSignal::set_ms_show(bool show) -{ - _probe->ms_show = show; - _view->set_update(_viewport, true); -} - -bool DsoSignal::get_ms_show() const +void DsoSignal::set_show(bool show) { - return _probe->ms_show; + _show = show; } -bool DsoSignal::get_ms_show_hover() const +bool DsoSignal::show() const { - return _ms_show_hover; + return _show; } -bool DsoSignal::get_ms_gear_hover() const +QString DsoSignal::get_measure(enum DSO_MEASURE_TYPE type) { - return _ms_gear_hover; -} - -void DsoSignal::set_ms_en(int index, bool en) -{ - assert(index > DSO_MS_BEGIN); - assert(index < DSO_MS_END); - - _probe->ms_en[index] = en; -} - -bool DsoSignal::get_ms_en(int index) const -{ - assert(index > DSO_MS_BEGIN); - assert(index < DSO_MS_END); - - return _probe->ms_en[index]; -} - -QString DsoSignal::get_ms_string(int index) const -{ - assert(index > DSO_MS_BEGIN); - assert(index < DSO_MS_END); - - switch(index) { - case DSO_MS_FREQ: return "Frequency"; - case DSO_MS_PERD: return "Period"; - case DSO_MS_VMAX: return "Vmax"; - case DSO_MS_VMIN: return "Vmin"; - case DSO_MS_VRMS: return "Vrms"; - case DSO_MS_VMEA: return "Vmean"; - case DSO_MS_VP2P: return "Vp-p"; - default: return "Error: Out of Bounds"; + const QString mNone = "--"; + QString mString; + if (_mValid) { + const int hw_offset = get_hw_offset(); + switch(type) { + case DSO_MS_AMPT: + if (_level_valid) + mString = get_voltage(_high - _low, 2); + else + mString = mNone; + break; + case DSO_MS_VHIG: + if (_level_valid) + mString = get_voltage(hw_offset - _low, 2); + else + mString = mNone; + break; + case DSO_MS_VLOW: + if (_level_valid) + mString = get_voltage(hw_offset - _high, 2); + else + mString = mNone; + break; + case DSO_MS_VP2P: + mString = get_voltage(_max - _min, 2); + break; + case DSO_MS_VMAX: + mString = get_voltage(hw_offset - _min, 2); + break; + case DSO_MS_VMIN: + mString = get_voltage(hw_offset - _max, 2); + break; + case DSO_MS_PERD: + mString = get_time(_period); + break; + case DSO_MS_FREQ: + mString = (abs(_period) > 1000000 ? QString::number(1000000000/_period, 'f', 2) + "Hz" : + abs(_period) > 1000 ? QString::number(1000000/_period, 'f', 2) + "kHz" : QString::number(1000/_period, 'f', 2) + "MHz"); + break; + case DSO_MS_VRMS: + mString = get_voltage(_rms, 2); + break; + case DSO_MS_VMEA: + mString = get_voltage(_mean, 2); + break; + case DSO_MS_NOVR: + if (_level_valid) + mString = QString::number((_max - _high) * 100.0 / (_high - _low), 'f', 2) + "%"; + else + mString = mNone; + break; + case DSO_MS_POVR: + if (_level_valid) + mString = QString::number((_low - _min) * 100.0 / (_high - _low), 'f', 2) + "%"; + else + mString = mNone; + break; + case DSO_MS_PDUT: + if (_level_valid) + mString = QString::number(_high_time/_period*100, 'f', 2)+"%"; + else + mString = mNone; + break; + case DSO_MS_NDUT: + if (_level_valid) + mString = QString::number(100 - _high_time/_period*100, 'f', 2)+"%"; + else + mString = mNone; + break; + case DSO_MS_PWDT: + if (_level_valid) + mString = get_time(_high_time); + else + mString = mNone; + break; + case DSO_MS_NWDT: + if (_level_valid) + mString = get_time(_period - _high_time); + else + mString = mNone; + break; + case DSO_MS_RISE: + if (_level_valid) + mString = get_time(_rise_time); + else + mString = mNone; + break; + case DSO_MS_FALL: + if (_level_valid) + mString = get_time(_fall_time); + else + mString = mNone; + break; + case DSO_MS_BRST: + if (_level_valid) + mString = get_time(_burst_time); + else + mString = mNone; + break; + case DSO_MS_PCNT: + if (_level_valid) + mString = (_pcount > 1000000 ? QString::number(_pcount/1000000, 'f', 6) + "M" : + _pcount > 1000 ? QString::number(_pcount/1000, 'f', 3) + "K" : QString::number(_pcount, 'f', 0)); + else + mString = mNone; + break; + default: + mString = "Error"; + break; + } + } else { + mString = mNone; } -} - -void DsoSignal::update_vpos() -{ - double vpos_off = (0.5 - _zero_vrate) * _vDial->get_value() * DS_CONF_DSO_VDIVS; - _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_VPOS, - g_variant_new_double(vpos_off)); + return mString; } QRect DsoSignal::get_view_rect() const @@ -592,29 +691,35 @@ QRect DsoSignal::get_view_rect() const _viewport->height() - UpMargin - DownMargin); } -void DsoSignal::paint_back(QPainter &p, int left, int right) +void DsoSignal::paint_back(QPainter &p, int left, int right, QColor fore, QColor back) { assert(_view); + if (!_show) + return; + int i, j; const int height = get_view_rect().height(); const int width = right - left; - QPen solidPen(Signal::dsFore); + fore.setAlpha(View::BackAlpha); + + QPen solidPen(fore); solidPen.setStyle(Qt::SolidLine); p.setPen(solidPen); - p.setBrush(Trace::dsBack); + p.setBrush(back.black() > 0x80 ? back.darker() : back.lighter()); p.drawRect(left, UpMargin, width, height); - p.setPen(Trace::dsLightBlue); - p.drawLine(left, UpMargin/2, left + width, UpMargin/2); + // draw zoom region + fore.setAlpha(View::ForeAlpha); + p.setPen(fore); const uint64_t sample_len = _view->session().cur_samplelimits(); const double samplerate = _view->session().cur_samplerate(); const double samples_per_pixel = samplerate * _view->scale(); const double shown_rate = min(samples_per_pixel * width * 1.0 / sample_len, 1.0); const double start = _view->offset() * samples_per_pixel; const double shown_offset = min(start / sample_len, 1.0) * width; - const double shown_len = shown_rate * width; + const double shown_len = max(shown_rate * width, 6.0); const QPointF left_edge[] = {QPoint(shown_offset + 3, UpMargin/2 - 6), QPoint(shown_offset, UpMargin/2 - 6), QPoint(shown_offset, UpMargin/2 + 6), @@ -623,12 +728,16 @@ void DsoSignal::paint_back(QPainter &p, int left, int right) QPoint(shown_offset + shown_len , UpMargin/2 - 6), QPoint(shown_offset + shown_len , UpMargin/2 + 6), QPoint(shown_offset + shown_len - 3, UpMargin/2 + 6)}; + p.drawLine(left, UpMargin/2, shown_offset, UpMargin/2); + p.drawLine(shown_offset + shown_len, UpMargin/2, left + width, UpMargin/2); p.drawPolyline(left_edge, countof(left_edge)); p.drawPolyline(right_edge, countof(right_edge)); - p.setBrush(Trace::dsBlue); + p.setBrush(fore); p.drawRect(shown_offset, UpMargin/2 - 3, shown_len, 6); - QPen dashPen(Signal::dsFore); + // draw divider + fore.setAlpha(View::BackAlpha); + QPen dashPen(fore); dashPen.setStyle(Qt::DashLine); p.setPen(dashPen); const double spanY =height * 1.0 / DS_CONF_DSO_VDIVS; @@ -653,19 +762,32 @@ void DsoSignal::paint_back(QPainter &p, int left, int right) posX - miniSpanX * j, height / 2.0f + UpMargin + 5); } } + _view->set_back(true); } -void DsoSignal::paint_mid(QPainter &p, int left, int right) +void DsoSignal::paint_mid(QPainter &p, int left, int right, QColor fore, QColor back) { + (void)fore; + (void)back; + + if (!_show) + return; + assert(_data); assert(_view); assert(right >= left); + { + if (_view->session().dso_feed()) { + _mValid = false; + _view->session().set_dso_feed(false); + } + } + if (enabled()) { - const float top = get_view_rect().top(); - const int height = get_view_rect().height(); + const int index = get_index(); const int width = right - left; - const float zeroY = _zero_vrate * height + top; + const float zeroY = get_zero_vpos(); const double scale = _view->scale(); assert(scale > 0); @@ -680,14 +802,14 @@ void DsoSignal::paint_mid(QPainter &p, int left, int right) if (snapshot->empty()) return; - if (!snapshot->has_data(get_index())) + if (!snapshot->has_data(index)) return; - const uint16_t number_channels = snapshot->get_channel_num(); + const uint16_t enabled_channels = snapshot->get_channel_num(); const double pixels_offset = offset; - //const double samplerate = _data->samplerate(); + const double samplerate = _data->samplerate(); //const double samplerate = _dev_inst->get_sample_rate(); - const double samplerate = _view->session().cur_samplerate(); + //const double samplerate = _view->session().cur_samplerate(); const int64_t last_sample = max((int64_t)(snapshot->get_sample_count() - 1), (int64_t)0); const double samples_per_pixel = samplerate * scale; const double start = offset * samples_per_pixel; @@ -697,33 +819,78 @@ void DsoSignal::paint_mid(QPainter &p, int left, int right) (int64_t)0), last_sample); const int64_t end_sample = min(max((int64_t)ceil(end) + 1, (int64_t)0), last_sample); + const int hw_offset = get_hw_offset(); if (samples_per_pixel < EnvelopeThreshold) { snapshot->enable_envelope(false); paint_trace(p, snapshot, zeroY, left, - start_sample, end_sample, - pixels_offset, samples_per_pixel, number_channels); + start_sample, end_sample, hw_offset, + pixels_offset, samples_per_pixel, enabled_channels); } else { snapshot->enable_envelope(true); paint_envelope(p, snapshot, zeroY, left, - start_sample, end_sample, - pixels_offset, samples_per_pixel, number_channels); + start_sample, end_sample, hw_offset, + pixels_offset, samples_per_pixel, enabled_channels); + } + + sr_status status; + if (sr_status_get(_dev_inst->dev_inst(), &status, false, 0, 0) == SR_OK) { + _mValid = true; + if (status.measure_valid) { + _min = (index == 0) ? status.ch0_min : status.ch1_min; + _max = (index == 0) ? status.ch0_max : status.ch1_max; + + _level_valid = (index == 0) ? status.ch0_level_valid : status.ch1_level_valid; + _low = (index == 0) ? status.ch0_low_level : status.ch1_low_level; + _high = (index == 0) ? status.ch0_high_level : status.ch1_high_level; + + const uint32_t count = (index == 0) ? status.ch0_cyc_cnt : status.ch1_cyc_cnt; + const bool plevel = (index == 0) ? status.ch0_plevel : status.ch1_plevel; + const bool startXORend = (index == 0) ? (status.ch0_cyc_llen == 0) : (status.ch1_cyc_llen == 0); + const uint16_t total_channels = g_slist_length(_dev_inst->dev_inst()->channels); + const double tfactor = (total_channels / enabled_channels) * SR_GHZ(1) * 1.0 / samplerate; + + double samples = (index == 0) ? status.ch0_cyc_tlen : status.ch1_cyc_tlen; + _period = ((count == 0) ? 0 : samples / count) * tfactor; + + samples = (index == 0) ? status.ch0_cyc_flen : status.ch1_cyc_flen; + _rise_time = ((count == 0) ? 0 : samples / ((plevel && startXORend) ? count : count + 1)) * tfactor; + samples = (index == 0) ? status.ch0_cyc_rlen : status.ch1_cyc_rlen; + _fall_time = ((count == 0) ? 0 : samples / ((!plevel && startXORend) ? count : count + 1)) * tfactor; + + samples = (index == 0) ? (status.ch0_plevel ? status.ch0_cyc_plen - status.ch0_cyc_llen : + status.ch0_cyc_tlen - status.ch0_cyc_plen + status.ch0_cyc_llen) : + (status.ch1_plevel ? status.ch1_cyc_plen - status.ch1_cyc_llen : + status.ch1_cyc_tlen - status.ch1_cyc_plen + status.ch1_cyc_llen); + _high_time = ((count == 0) ? 0 : samples / count) * tfactor; + + samples = (index == 0) ? status.ch0_cyc_tlen + status.ch0_cyc_llen : status.ch1_cyc_flen + status.ch1_cyc_llen; + _burst_time = samples * tfactor; + + _pcount = count + (plevel & !startXORend); + _rms = (index == 0) ? status.ch0_acc_square : status.ch1_acc_square; + _rms = sqrt(_rms / snapshot->get_sample_count()); + _mean = (index == 0) ? status.ch0_acc_mean : status.ch1_acc_mean; + _mean = hw_offset - _mean / snapshot->get_sample_count(); + } } } } -void DsoSignal::paint_fore(QPainter &p, int left, int right) +void DsoSignal::paint_fore(QPainter &p, int left, int right, QColor fore, QColor back) { - assert(_view); + if (!_show) + return; - bool antialiasing = p.Antialiasing; - p.setRenderHint(QPainter::Antialiasing, false); + assert(_view); - QPen pen(Signal::dsGray); + fore.setAlpha(View::BackAlpha); + QPen pen(fore); pen.setStyle(Qt::DotLine); p.setPen(pen); p.drawLine(left, get_zero_vpos(), right, get_zero_vpos()); + fore.setAlpha(View::ForeAlpha); if(enabled()) { const QPointF mouse_point = _view->hover_point(); const QRectF label_rect = get_trig_rect(left, right); @@ -731,7 +898,7 @@ void DsoSignal::paint_fore(QPainter &p, int left, int right) // Paint the trig line const QPointF points[] = { - QPointF(right, get_trig_vpos()), + QPointF(right, ratio2pos(get_trig_vrate())), label_rect.topLeft(), label_rect.topRight(), label_rect.bottomRight(), @@ -742,7 +909,7 @@ void DsoSignal::paint_fore(QPainter &p, int left, int right) p.setBrush(_colour); p.drawPolygon(points, countof(points)); - p.setPen(Qt::white); + p.setPen(fore); const QPointF arrow_points[] = { QPoint(label_rect.left(), label_rect.center().y()), QPoint(label_rect.left(), label_rect.center().y()-1), @@ -770,13 +937,12 @@ void DsoSignal::paint_fore(QPainter &p, int left, int right) p.drawPoints(arrow_points, countof(arrow_points)); // paint the trig voltage - int trigp = get_trig_vpos(); - float t_vol = (_zero_vrate - get_trig_vrate()) * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS; - QString t_vol_s = (_vDial->get_value() >= 500) ? QString::number(t_vol/1000.0f, 'f', 2)+"V" : QString::number(t_vol, 'f', 2)+"mV"; + int trigp = ratio2pos(get_trig_vrate()); + QString t_vol_s = get_voltage(get_zero_vpos() - trigp, 2, true); int vol_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, Qt::AlignLeft | Qt::AlignTop, t_vol_s).width(); const QRectF t_vol_rect = QRectF(right-vol_width, trigp-10, vol_width, 20); - p.setPen(Qt::white); + p.setPen(fore); p.drawText(t_vol_rect, Qt::AlignRight | Qt::AlignVCenter, t_vol_s); // paint the _trig_vpos line @@ -786,14 +952,16 @@ void DsoSignal::paint_fore(QPainter &p, int left, int right) } // Paint the text - p.setPen(Qt::white); + p.setPen(fore); p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "T"); // Paint measure - paint_measure(p); - } + if (_view->session().get_capture_state() == SigSession::Stopped) + paint_hover_measure(p, fore, back); - p.setRenderHint(QPainter::Antialiasing, antialiasing); + // autoset + auto_set(); + } } QRectF DsoSignal::get_trig_rect(int left, int right) const @@ -801,13 +969,13 @@ QRectF DsoSignal::get_trig_rect(int left, int right) const (void)left; return QRectF(right + SquareWidth / 2, - get_trig_vpos() - SquareWidth / 2, + ratio2pos(get_trig_vrate()) - SquareWidth / 2, SquareWidth, SquareWidth); } void DsoSignal::paint_trace(QPainter &p, const boost::shared_ptr &snapshot, - int zeroY, int left, const int64_t start, const int64_t end, + int zeroY, int left, const int64_t start, const int64_t end, int hw_offset, const double pixels_offset, const double samples_per_pixel, uint64_t num_channels) { const int64_t sample_count = end - start + 1; @@ -817,7 +985,7 @@ void DsoSignal::paint_trace(QPainter &p, assert(samples); QColor trace_colour = _colour; - trace_colour.setAlpha(150); + trace_colour.setAlpha(View::ForeAlpha); p.setPen(trace_colour); QPointF *points = new QPointF[sample_count]; @@ -827,32 +995,26 @@ void DsoSignal::paint_trace(QPainter &p, float bottom = get_view_rect().bottom(); float x = (start / samples_per_pixel - pixels_offset) + left; double pixels_per_sample = 1.0/samples_per_pixel; - uint8_t offset; + uint8_t value; int64_t sample_end = sample_count*num_channels; for (int64_t sample = 0; sample < sample_end; sample+=num_channels) { - //const float x = (sample / samples_per_pixel - pixels_offset) + left; - //uint8_t offset = samples[(sample - start)*num_channels]; - - //offset = samples[(sample - start)*num_channels]; - offset = samples[sample]; - const float y = min(max(top, zeroY + (offset - _hw_offset) * _scale), bottom); + value = samples[sample]; + const float y = min(max(top, zeroY + (value - hw_offset) * _scale), bottom); *point++ = QPointF(x, y); x += pixels_per_sample; - //*point++ = QPointF(x, top + offset); } p.drawPolyline(points, point - points); p.eraseRect(get_view_rect().right()+1, get_view_rect().top(), _view->viewport()->width() - get_view_rect().width(), get_view_rect().height()); - //delete[] samples; delete[] points; } } void DsoSignal::paint_envelope(QPainter &p, const boost::shared_ptr &snapshot, - int zeroY, int left, const int64_t start, const int64_t end, + int zeroY, int left, const int64_t start, const int64_t end, int hw_offset, const double pixels_offset, const double samples_per_pixel, uint64_t num_channels) { using namespace Qt; @@ -868,7 +1030,7 @@ void DsoSignal::paint_envelope(QPainter &p, p.setPen(QPen(NoPen)); //p.setPen(QPen(_colour, 2, Qt::SolidLine)); QColor envelope_colour = _colour; - envelope_colour.setAlpha(150); + envelope_colour.setAlpha(View::ForeAlpha); p.setBrush(envelope_colour); QRectF *const rects = new QRectF[e.length]; @@ -883,8 +1045,8 @@ void DsoSignal::paint_envelope(QPainter &p, // We overlap this sample with the next so that vertical // gaps do not appear during steep rising or falling edges - const float b = min(max(top, ((max(s->max, (s+1)->min) - _hw_offset) * _scale + zeroY)), bottom); - const float t = min(max(top, ((min(s->min, (s+1)->max) - _hw_offset) * _scale + zeroY)), bottom); + const float b = min(max(top, ((max(s->max, (s+1)->min) - hw_offset) * _scale + zeroY)), bottom); + const float t = min(max(top, ((min(s->min, (s+1)->max) - hw_offset) * _scale + zeroY)), bottom); float h = b - t; if(h >= 0.0f && h <= 1.0f) @@ -901,8 +1063,12 @@ void DsoSignal::paint_envelope(QPainter &p, //delete[] e.samples; } -void DsoSignal::paint_type_options(QPainter &p, int right, const QPoint pt) +void DsoSignal::paint_type_options(QPainter &p, int right, const QPoint pt, QColor fore) { + p.setRenderHint(QPainter::Antialiasing, true); + + QColor foreBack = fore; + foreBack.setAlpha(View::BackAlpha); int y = get_y(); const QRectF vDial_rect = get_rect(DSO_VDIAL, y, right); const QRectF x1_rect = get_rect(DSO_X1, y, right); @@ -912,27 +1078,39 @@ void DsoSignal::paint_type_options(QPainter &p, int right, const QPoint pt) const QRectF chEn_rect = get_rect(DSO_CHEN, y, right); const QRectF auto_rect = get_rect(DSO_AUTO, y, right); - _vDial->paint(p, vDial_rect, _colour, pt); - + QString pText; + _vDial->paint(p, vDial_rect, _colour, pt, pText); + QFontMetrics fm(p.font()); + const QRectF valueRect = QRectF(chEn_rect.left(), vDial_rect.top()-fm.height()-10, right, fm.height()); + p.drawText(valueRect, Qt::AlignCenter, pText); + + const char *strings[6] = { + QT_TR_NOOP("EN"), + QT_TR_NOOP("DIS"), + QT_TR_NOOP("GND"), + QT_TR_NOOP("DC"), + QT_TR_NOOP("AC"), + QT_TR_NOOP("AUTO"), + }; p.setPen(Qt::transparent); p.setBrush(chEn_rect.contains(pt) ? _colour.darker() : _colour); p.drawRect(chEn_rect); p.setPen(Qt::white); - p.drawText(chEn_rect, Qt::AlignCenter | Qt::AlignVCenter, enabled() ? tr("EN") : tr("DIS")); + p.drawText(chEn_rect, Qt::AlignCenter | Qt::AlignVCenter, enabled() ? tr(strings[0]) : tr(strings[1])); p.setPen(Qt::transparent); - p.setBrush(enabled() ? (acdc_rect.contains(pt) ? _colour.darker() : _colour) : dsDisable); + p.setBrush(enabled() ? (acdc_rect.contains(pt) ? _colour.darker() : _colour) : foreBack); p.drawRect(acdc_rect); p.setPen(Qt::white); - p.drawText(acdc_rect, Qt::AlignCenter | Qt::AlignVCenter, (_acCoupling == SR_GND_COUPLING) ? tr("GND") : - (_acCoupling == SR_DC_COUPLING) ? tr("DC") : tr("AC")); + p.drawText(acdc_rect, Qt::AlignCenter | Qt::AlignVCenter, (_acCoupling == SR_GND_COUPLING) ? tr(strings[2]): + (_acCoupling == SR_DC_COUPLING) ? tr(strings[3]) : tr(strings[4])); if (!_dev_inst->name().contains("virtual")) { p.setPen(Qt::transparent); - p.setBrush(enabled() ? (auto_rect.contains(pt) ? _colour.darker() : _colour) : dsDisable); + p.setBrush(enabled() ? (auto_rect.contains(pt) ? _colour.darker() : _colour) : foreBack); p.drawRect(auto_rect); p.setPen(Qt::white); - p.drawText(auto_rect, Qt::AlignCenter | Qt::AlignVCenter, tr("AUTO")); + p.drawText(auto_rect, Qt::AlignCenter | Qt::AlignVCenter, tr(strings[5])); } // paint the probe factor selector @@ -948,17 +1126,19 @@ void DsoSignal::paint_type_options(QPainter &p, int right, const QPoint pt) } p.setPen(Qt::transparent); - p.setBrush((enabled() && (factor == 100)) ? (x100_rect.contains(pt) ? _colour.darker() : _colour) : (x100_rect.contains(pt) ? _colour.darker() : dsDisable)); + p.setBrush((enabled() && (factor == 100)) ? (x100_rect.contains(pt) ? _colour.darker() : _colour) : (x100_rect.contains(pt) ? _colour.darker() : foreBack)); p.drawRect(x100_rect); - p.setBrush((enabled() && (factor == 10)) ? (x10_rect.contains(pt) ? _colour.darker() : _colour) : (x10_rect.contains(pt) ? _colour.darker() : dsDisable)); + p.setBrush((enabled() && (factor == 10)) ? (x10_rect.contains(pt) ? _colour.darker() : _colour) : (x10_rect.contains(pt) ? _colour.darker() : foreBack)); p.drawRect(x10_rect); - p.setBrush((enabled() && (factor == 1)) ? (x1_rect.contains(pt) ? _colour.darker() : _colour) : (x1_rect.contains(pt) ? _colour.darker() : dsDisable)); + p.setBrush((enabled() && (factor == 1)) ? (x1_rect.contains(pt) ? _colour.darker() : _colour) : (x1_rect.contains(pt) ? _colour.darker() : foreBack)); p.drawRect(x1_rect); p.setPen(Qt::white); p.drawText(x100_rect, Qt::AlignCenter | Qt::AlignVCenter, "x100"); p.drawText(x10_rect, Qt::AlignCenter | Qt::AlignVCenter, "x10"); p.drawText(x1_rect, Qt::AlignCenter | Qt::AlignVCenter, "x1"); + + p.setRenderHint(QPainter::Antialiasing, false); } bool DsoSignal::mouse_press(int right, const QPoint pt) @@ -981,9 +1161,9 @@ bool DsoSignal::mouse_press(int right, const QPoint pt) } else if (enabled()) { if (vDial_rect.contains(pt) && pt.x() > vDial_rect.center().x()) { if (pt.y() > vDial_rect.center().y()) - go_vDialNext(); + go_vDialNext(true); else - go_vDialPre(); + go_vDialPre(true); } else if (_dev_inst->name() != "virtual-session" && acdc_rect.contains(pt)) { if (_dev_inst->name() == "DSLogic") @@ -1014,9 +1194,9 @@ bool DsoSignal::mouse_wheel(int right, const QPoint pt, const int shift) if (vDial_rect.contains(pt)) { if (shift > 0.5) - go_vDialPre(); + go_vDialPre(true); else if (shift < -0.5) - go_vDialNext(); + go_vDialNext(true); return true; } else { return false; @@ -1068,147 +1248,126 @@ QRectF DsoSignal::get_rect(DsoSetRegions type, int y, int right) return QRectF(0, 0, 0, 0); } -void DsoSignal::paint_measure(QPainter &p) +void DsoSignal::paint_hover_measure(QPainter &p, QColor fore, QColor back) { - sr_status status; - int index = get_index(); - const int st_begin = (index == 0) ? SR_STATUS_CH0_BEGIN : SR_STATUS_CH1_BEGIN; - const int st_end = (index == 0) ? SR_STATUS_CH0_END : SR_STATUS_CH1_END; - if (sr_status_get(_dev_inst->dev_inst(), &status, false, st_begin, st_end) == SR_OK) { - _max = (index == 0) ? status.ch0_max : status.ch1_max; - _min = (index == 0) ? status.ch0_min : status.ch1_min; - const uint64_t period = (index == 0) ? status.ch0_period : status.ch1_period; - const uint32_t count = (index == 0) ? status.ch0_pcnt : status.ch1_pcnt; - double value_max = (_hw_offset - _min) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height(); - double value_min = (_hw_offset - _max) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height(); - double value_p2p = value_max - value_min; - _period = (count == 0) ? 0 : period * 10.0 / count; - const int channel_count = _view->session().get_ch_num(SR_CHANNEL_DSO); - uint64_t sample_rate = _dev_inst->get_sample_rate(); - _period = _period * 200.0 / (channel_count * sample_rate * 1.0 / SR_MHZ(1)); - _ms_string[DSO_MS_VMAX] = tr("Vmax: ") + (abs(value_max) > 1000 ? QString::number(value_max/1000.0, 'f', 2) + "V" : QString::number(value_max, 'f', 2) + "mV"); - _ms_string[DSO_MS_VMIN] = tr("Vmin: ") + (abs(value_min) > 1000 ? QString::number(value_min/1000.0, 'f', 2) + "V" : QString::number(value_min, 'f', 2) + "mV"); - _ms_string[DSO_MS_PERD] = tr("Perd: ") + (abs(_period) > 1000000000 ? QString::number(_period/1000000000, 'f', 2) + "S" : - abs(_period) > 1000000 ? QString::number(_period/1000000, 'f', 2) + "mS" : - abs(_period) > 1000 ? QString::number(_period/1000, 'f', 2) + "uS" : QString::number(_period, 'f', 2) + "nS"); - _ms_string[DSO_MS_FREQ] = tr("Freq: ") + (abs(_period) > 1000000 ? QString::number(1000000000/_period, 'f', 2) + "Hz" : - abs(_period) > 1000 ? QString::number(1000000/_period, 'f', 2) + "kHz" : QString::number(1000/_period, 'f', 2) + "MHz"); - _ms_string[DSO_MS_VP2P] = tr("Vp-p: ") + (abs(value_p2p) > 1000 ? QString::number(value_p2p/1000.0, 'f', 2) + "V" : QString::number(value_p2p, 'f', 2) + "mV"); - - if (_probe->ms_show && _probe->ms_en[DSO_MS_VRMS]) { - const deque< boost::shared_ptr > &snapshots = - _data->get_snapshots(); - if (!snapshots.empty()) { - const boost::shared_ptr &snapshot = - snapshots.front(); - const double vrms = snapshot->cal_vrms(_hw_offset, get_index()); - const double value_vrms = vrms * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height(); - _ms_string[DSO_MS_VRMS] = tr("Vrms: ") + (abs(value_vrms) > 1000 ? QString::number(value_vrms/1000.0, 'f', 2) + "V" : QString::number(value_vrms, 'f', 2) + "mV"); - } - } - - if (_probe->ms_show && _probe->ms_en[DSO_MS_VMEA]) { - const deque< boost::shared_ptr > &snapshots = - _data->get_snapshots(); - if (!snapshots.empty()) { - const boost::shared_ptr &snapshot = - snapshots.front(); - const double vmean = snapshot->cal_vmean(get_index()); - const double value_vmean = (_hw_offset - vmean) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height(); - _ms_string[DSO_MS_VMEA] = tr("Vmean: ") + (abs(value_vmean) > 1000 ? QString::number(value_vmean/1000.0, 'f', 2) + "V" : QString::number(value_vmean, 'f', 2) + "mV"); - } - } - } else { - _ms_string[DSO_MS_VMAX] = tr("Vmax: #####"); - _ms_string[DSO_MS_VMIN] = tr("Vmin: #####"); - _ms_string[DSO_MS_PERD] = tr("Perd: #####"); - _ms_string[DSO_MS_FREQ] = tr("Freq: #####"); - _ms_string[DSO_MS_VP2P] = tr("Vp-p: #####"); - _ms_string[DSO_MS_VRMS] = tr("Vrms: #####"); - _ms_string[DSO_MS_VMEA] = tr("Vmean: #####"); + const int hw_offset = get_hw_offset(); + // Hover measure + if (_hover_en) { + QString hover_str = get_voltage(hw_offset - _hover_value, 2); + const int hover_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, + Qt::AlignLeft | Qt::AlignTop, hover_str).width() + 10; + const int hover_height = p.boundingRect(0, 0, INT_MAX, INT_MAX, + Qt::AlignLeft | Qt::AlignTop, hover_str).height(); + QRectF hover_rect(_hover_point.x(), _hover_point.y()-hover_height/2, hover_width, hover_height); + if (hover_rect.right() > get_view_rect().right()) + hover_rect.moveRight(_hover_point.x()); + if (hover_rect.top() < get_view_rect().top()) + hover_rect.moveTop(_hover_point.y()); + if (hover_rect.bottom() > get_view_rect().bottom()) + hover_rect.moveBottom(_hover_point.y()); + + p.setPen(fore); + p.setBrush(back); + p.drawRect(_hover_point.x()-1, _hover_point.y()-1, HoverPointSize, HoverPointSize); + p.drawText(hover_rect, Qt::AlignCenter | Qt::AlignTop | Qt::TextDontClip, hover_str); } - QColor measure_colour = _colour; - measure_colour.setAlpha(180); - QColor back_colour = Qt::white; - back_colour.setAlpha(100); - - bool antialiasing = p.Antialiasing; - p.setRenderHint(QPainter::Antialiasing, true); - - p.setPen(Qt::NoPen); - p.setBrush(measure_colour); - p.drawRoundedRect(_ms_rect[DSO_MS_BEGIN], MS_RectRad, MS_RectRad); - const QPixmap gear_pix(":/icons/settings.png"); - const QPixmap show_pix(_probe->ms_show ? ":/icons/shown.png" : ":/icons/hidden.png"); - if (_ms_gear_hover) { - p.setBrush(back_colour); - p.drawRoundedRect(_ms_gear_rect, MS_RectRad, MS_RectRad); - } else if (_ms_show_hover) { - p.setBrush(back_colour); - p.drawRoundedRect(_ms_show_rect, MS_RectRad, MS_RectRad); - } - p.drawPixmap(_ms_gear_rect, gear_pix); - p.drawPixmap(_ms_show_rect, show_pix); - p.setPen(Qt::white); - p.drawText(_ms_rect[DSO_MS_BEGIN], Qt::AlignCenter | Qt::AlignVCenter, "CH"+QString::number(index)); - - if (_probe->ms_show) { - p.setBrush(back_colour); - int j = DSO_MS_BEGIN+1; - for (int i=DSO_MS_BEGIN+1; ims_en[i]) { - p.setPen(_colour); - p.drawText(_ms_rect[j], Qt::AlignLeft | Qt::AlignVCenter, _ms_string[i]); - p.setPen(Qt::NoPen); - p.drawRoundedRect(_ms_rect[j], MS_RectRad, MS_RectRad); - j++; - } - } + list::iterator i = _view->get_cursorList().begin(); + while (i != _view->get_cursorList().end()) { + float pt_value; + const QPointF pt = get_point((*i)->index(), pt_value); + QString pt_str = get_voltage(hw_offset - pt_value, 2); + const int pt_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, + Qt::AlignLeft | Qt::AlignTop, pt_str).width() + 10; + const int pt_height = p.boundingRect(0, 0, INT_MAX, INT_MAX, + Qt::AlignLeft | Qt::AlignTop, pt_str).height(); + QRectF pt_rect(pt.x(), pt.y()-pt_height/2, pt_width, pt_height); + if (pt_rect.right() > get_view_rect().right()) + pt_rect.moveRight(pt.x()); + if (pt_rect.top() < get_view_rect().top()) + pt_rect.moveTop(pt.y()); + if (pt_rect.bottom() > get_view_rect().bottom()) + pt_rect.moveBottom(pt.y()); + + p.drawRect(pt.x()-1, pt.y()-1, 2, 2); + p.drawLine(pt.x()-2, pt.y()-2, pt.x()+2, pt.y()+2); + p.drawLine(pt.x()+2, pt.y()-2, pt.x()-2, pt.y()+2); + p.drawText(pt_rect, Qt::AlignCenter | Qt::AlignTop | Qt::TextDontClip, pt_str); + + i++; } - p.setRenderHint(QPainter::Antialiasing, antialiasing); +} +void DsoSignal::auto_set() +{ if (_view->session().get_capture_state() == SigSession::Stopped) { if (_autoV) autoV_end(); if (_autoH) autoH_end(); - } - - if (_autoV && !_view->session().get_data_auto_lock()) { - set_zero_vrate(0.5, true); - const uint8_t vscale = abs(_max - _min); - if (_max == 0xff || _min == 0x00 || vscale > 0xCC) { - go_vDialNext(); - } else if (vscale > 0x33) { - autoV_end(); - } else { - go_vDialPre(); + } else { + if (_autoH && _autoV && get_zero_ratio() != 0.5) { + set_zero_ratio(0.5); } - _view->session().data_auto_lock(AutoLock); - } - - if (_autoH && !_view->session().get_data_auto_lock()) { - const double hori_res = _view->get_hori_res(); - if (_period <= 0) { - _view->zoom(-1); - } else if (_period < 1.5*hori_res) { - _view->zoom(1); - } else if (_period > 6*hori_res) { - _view->zoom(-1); - } else { - autoH_end(); + if (_mValid && !_view->session().get_data_auto_lock()) { + if (_autoH) { + bool roll = false; + GVariant *gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_ROLL); + if (gvar != NULL) { + roll = g_variant_get_boolean(gvar); + g_variant_unref(gvar); + } + const double hori_res = _view->get_hori_res(); + if (_level_valid && ((!roll && _pcount < 3) || _period > 4*hori_res)) { + _view->zoom(-1); + } else if (_level_valid && _pcount > 6 && _period < 1.5*hori_res) { + _view->zoom(1); + } else if (_level_valid) { + autoH_end(); + } + } + if (_autoV) { + const bool over_flag = _max == 0xff || _min == 0x0; + const bool out_flag = _max >= 0xE0 || _min <= 0x20; + const bool under_flag = _max <= 0xA0 && _min >= 0x60; + if (over_flag) { + if (!_autoV_over) + _auto_cnt = 0; + _autoV_over = true; + go_vDialNext(false); + } else if (out_flag) { + go_vDialNext(false); + } else if (!_autoV_over && under_flag) { + go_vDialPre(false); + } else if (!_autoH) { + autoV_end(); + } + + if (_autoV_over && under_flag) { + if (_auto_cnt++ > 16) + _autoV_over = false; + } else { + _auto_cnt = 0; + } + + if (_level_valid) { + _trig_value = (_min+_max)/2; + set_trig_vpos(ratio2pos(get_trig_vrate())); + } + } + if (_autoH || _autoV) + _view->session().data_auto_lock(AutoLock); } - _view->session().data_auto_lock(AutoLock); } } void DsoSignal::autoV_end() { _autoV = false; + _autoV_over = false; _view->auto_trig(get_index()); _trig_value = (_min+_max)/2; - set_trig_vpos(get_trig_vpos(), true); + set_trig_vpos(ratio2pos(get_trig_vrate())); _view->set_update(_viewport, true); _view->update(); } @@ -1236,31 +1395,17 @@ void DsoSignal::auto_start() _view->session().data_auto_lock(AutoLock); _autoV = true; _autoH = true; - QTimer::singleShot(AutoTime, this, SLOT(auto_end())); + QTimer::singleShot(AutoTime, &_view->session(), SLOT(auto_end())); } } bool DsoSignal::measure(const QPointF &p) { - if (_ms_gear_rect.contains(QPoint(p.x(), p.y()))) { - _ms_gear_hover = true; - _view->set_update(_viewport, true); - return false; - } else if (_ms_gear_hover) { - _view->set_update(_viewport, true); - _ms_gear_hover = false; - } - if (_ms_show_rect.contains(QPoint(p.x(), p.y()))) { - _ms_show_hover = true; - _view->set_update(_viewport, true); + _hover_en = false; + if (!enabled() || !show()) return false; - } else if (_ms_show_hover){ - _view->set_update(_viewport, true); - _ms_show_hover = false; - } - _hover_en = false; - if (!enabled()) + if (_view->session().get_capture_state() != SigSession::Stopped) return false; const QRectF window = get_view_rect(); @@ -1287,39 +1432,9 @@ bool DsoSignal::measure(const QPointF &p) if (_hover_index >= snapshot->get_sample_count()) return false; - uint64_t pre_index; - uint64_t nxt_index; - if (_hover_index > 0) - pre_index = _hover_index - 1; - else - pre_index = _hover_index; - if (_hover_index < snapshot->get_sample_count() - 1) - nxt_index = _hover_index + 1; - else - nxt_index = _hover_index; - const uint8_t pre_sample = *snapshot->get_samples(pre_index, pre_index, get_index()); - const uint8_t cur_sample = *snapshot->get_samples(_hover_index, _hover_index, get_index()); - const uint8_t nxt_sample = *snapshot->get_samples(nxt_index, nxt_index, get_index()); - - _hover_value = (_hw_offset - cur_sample) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height(); - - float top = get_view_rect().top(); - float bottom = get_view_rect().bottom(); - float zeroP = _zero_vrate * get_view_rect().height() + top; - float pre_x = (pre_index / samples_per_pixel - pixels_offset); - const float pre_y = min(max(top, zeroP + (pre_sample - _hw_offset)* _scale), bottom); - float x = (_hover_index / samples_per_pixel - pixels_offset); - const float y = min(max(top, zeroP + (cur_sample - _hw_offset)* _scale), bottom); - float nxt_x = (nxt_index / samples_per_pixel - pixels_offset); - const float nxt_y = min(max(top, zeroP + (nxt_sample - _hw_offset)* _scale), bottom); - const QRectF slope_rect = QRectF(QPointF(pre_x - 10, pre_y - 10), QPointF(nxt_x + 10, nxt_y + 10)); - if (abs(y-p.y()) < 20 || slope_rect.contains(p)) { - _hover_point = QPointF(x, y); - _hover_en = true; - return true; - } else { - return false; - } + _hover_point = get_point(_hover_index, _hover_value); + _hover_en = true; + return true; } bool DsoSignal::get_hover(uint64_t &index, QPointF &p, double &value) @@ -1333,5 +1448,84 @@ bool DsoSignal::get_hover(uint64_t &index, QPointF &p, double &value) return false; } +QPointF DsoSignal::get_point(uint64_t index, float &value) +{ + QPointF pt = QPointF(0, 0); + + if (!enabled()) + return pt; + + const deque< boost::shared_ptr > &snapshots = + _data->get_snapshots(); + if (snapshots.empty()) + return pt; + + const boost::shared_ptr &snapshot = + snapshots.front(); + if (snapshot->empty()) + return pt; + + const double scale = _view->scale(); + assert(scale > 0); + const int64_t pixels_offset = _view->offset(); + const double samplerate = _view->session().cur_samplerate(); + const double samples_per_pixel = samplerate * scale; + + if (index >= snapshot->get_sample_count()) + return pt; + + value = *snapshot->get_samples(index, index, get_index()); + const float top = get_view_rect().top(); + const float bottom = get_view_rect().bottom(); + const int hw_offset = get_hw_offset(); + const float x = (index / samples_per_pixel - pixels_offset); + const float y = min(max(top, get_zero_vpos() + (value - hw_offset)* _scale), bottom); + pt = QPointF(x, y); + + return pt; +} + +double DsoSignal::get_voltage(uint64_t index) +{ + if (!enabled()) + return 1; + + const deque< boost::shared_ptr > &snapshots = + _data->get_snapshots(); + if (snapshots.empty()) + return 1; + + const boost::shared_ptr &snapshot = + snapshots.front(); + if (snapshot->empty()) + return 1; + + if (index >= snapshot->get_sample_count()) + return 1; + + const double value = *snapshot->get_samples(index, index, get_index()); + const int hw_offset = get_hw_offset(); + return (hw_offset - value) * _scale * + _vDial->get_value() * _vDial->get_factor() * + DS_CONF_DSO_VDIVS / get_view_rect().height(); +} + +QString DsoSignal::get_voltage(double v, int p, bool scaled) +{ + if (scaled) + v = v * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height(); + else + v = v * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height(); + return abs(v) >= 1000 ? QString::number(v/1000.0, 'f', p) + "V" : QString::number(v, 'f', p) + "mV"; +} + +QString DsoSignal::get_time(double t) +{ + QString str = (abs(t) > 1000000000 ? QString::number(t/1000000000, 'f', 2) + "S" : + abs(t) > 1000000 ? QString::number(t/1000000, 'f', 2) + "mS" : + abs(t) > 1000 ? QString::number(t/1000, 'f', 2) + "uS" : QString::number(t, 'f', 2) + "nS"); + return str; +} + } // namespace view } // namespace pv diff --git a/DSView/pv/view/dsosignal.h b/DSView/pv/view/dsosignal.h old mode 100644 new mode 100755 index 5bd96ddfb2dbaa8f45022b2f4b2803fc25b4a41e..651ad98183393185e9e29d1e0653b579490b57d4 --- a/DSView/pv/view/dsosignal.h +++ b/DSView/pv/view/dsosignal.h @@ -40,22 +40,25 @@ namespace view { class DsoSignal : public Signal { + Q_OBJECT + +public: + static const int UpMargin = 30; + static const int DownMargin = 0; + static const int RightMargin = 30; + static const float EnvelopeThreshold; + static const int HoverPointSize = 2; + static const int RefreshShort = 200; + private: static const QColor SignalColours[4]; - static const float EnvelopeThreshold; - static const int HitCursorMargin = 3; static const uint64_t vDialValueStep = 1000; static const uint64_t vDialUnitCount = 2; static const QString vDialUnit[vDialUnitCount]; - static const int UpMargin = 30; - static const int DownMargin = 0; - static const int RightMargin = 30; - static const uint8_t DefaultBits = 8; static const int TrigMargin = 16; - static const int RefreshShort = 200; static const int RefreshLong = 800; static const int AutoTime = 10000; static const int AutoLock = 3; @@ -88,10 +91,12 @@ public: boost::shared_ptr data() const; boost::shared_ptr dso_data() const; - void set_viewport(pv::view::Viewport *viewport); void set_scale(int height); float get_scale(); + uint8_t get_bits(); + double get_ref_min() const; + double get_ref_max() const; int get_name_width() const; @@ -101,19 +106,23 @@ public: void set_enable(bool enable); bool get_vDialActive() const; void set_vDialActive(bool active); - bool go_vDialPre(); - bool go_vDialNext(); + bool go_vDialPre(bool manul); + bool go_vDialNext(bool manul); bool update_capture(bool instant); + dslDial *get_vDial() const; uint64_t get_vDialValue() const; uint16_t get_vDialSel() const; uint8_t get_acCoupling() const; void set_acCoupling(uint8_t coupling); - void set_trig_vpos(int pos, bool delta_change); - int get_trig_vpos() const; - void set_trig_vrate(double rate); + + void set_trig_vpos(int pos, bool delta_change = true); + void set_trig_ratio(double ratio, bool delta_change = true); double get_trig_vrate() const; + void set_factor(uint64_t factor); uint64_t get_factor(); + void set_show(bool show); + bool show() const; bool load_settings(); int commit_settings(); @@ -123,6 +132,7 @@ public: */ bool measure(const QPointF &p); bool get_hover(uint64_t &index, QPointF &p, double &value); + QPointF get_point(uint64_t index, float &value); /** * auto set the vertical and Horizontal scale @@ -130,19 +140,30 @@ public: void auto_start(); void autoV_end(); void autoH_end(); + void auto_end(); /** * Gets the mid-Y position of this signal. */ int get_zero_vpos() const; - double get_zero_vrate(); - double get_hw_offset(); + double get_zero_ratio() const; + int get_hw_offset() const; /** * Sets the mid-Y position of this signal. */ void set_zero_vpos(int pos); - void set_zero_vrate(double rate, bool force_update); - void update_vpos(); + void set_zero_ratio(double ratio); + double get_voltage(uint64_t index); + QString get_voltage(double v, int p, bool scaled = false); + QString get_time(double t); + + /** + * + */ + int ratio2value(double ratio) const; + int ratio2pos(double ratio) const; + double value2ratio(int value) const; + double pos2ratio(int pos) const; /** * Paints the background layer of the trace with a QPainter @@ -150,7 +171,7 @@ public: * @param left the x-coordinate of the left edge of the signal * @param right the x-coordinate of the right edge of the signal **/ - void paint_back(QPainter &p, int left, int right); + void paint_back(QPainter &p, int left, int right, QColor fore, QColor back); /** * Paints the signal with a QPainter @@ -158,7 +179,7 @@ public: * @param left the x-coordinate of the left edge of the signal. * @param right the x-coordinate of the right edge of the signal. **/ - void paint_mid(QPainter &p, int left, int right); + void paint_mid(QPainter &p, int left, int right, QColor fore, QColor back); /** * Paints the signal with a QPainter @@ -166,19 +187,13 @@ public: * @param left the x-coordinate of the left edge of the signal. * @param right the x-coordinate of the right edge of the signal. **/ - void paint_fore(QPainter &p, int left, int right); + void paint_fore(QPainter &p, int left, int right, QColor fore, QColor back); QRect get_view_rect() const; QRectF get_trig_rect(int left, int right) const; - void set_ms_show(bool show); - bool get_ms_show() const; - bool get_ms_show_hover() const; - bool get_ms_gear_hover() const; - void set_ms_en(int index, bool en); - bool get_ms_en(int index) const; - QString get_ms_string(int index) const; + QString get_measure(enum DSO_MEASURE_TYPE type); QRectF get_rect(DsoSetRegions type, int y, int right); @@ -186,61 +201,67 @@ public: bool mouse_wheel(int right, const QPoint pt, const int shift); -public slots: - void auto_end(); protected: - void paint_type_options(QPainter &p, int right, const QPoint pt); + void paint_type_options(QPainter &p, int right, const QPoint pt, QColor fore); private: - void paint_trace(QPainter &p, + void paint_trace(QPainter &p, const boost::shared_ptr &snapshot, - int zeroY, int left, const int64_t start, const int64_t end, + int zeroY, int left, const int64_t start, const int64_t end, int hw_offset, const double pixels_offset, const double samples_per_pixel, uint64_t num_channels); - void paint_envelope(QPainter &p, + void paint_envelope(QPainter &p, const boost::shared_ptr &snapshot, - int zeroY, int left, const int64_t start, const int64_t end, + int zeroY, int left, const int64_t start, const int64_t end, int hw_offset, const double pixels_offset, const double samples_per_pixel, uint64_t num_channels); - void paint_measure(QPainter &p); + void paint_hover_measure(QPainter &p, QColor fore, QColor back); + void auto_set(); private: boost::shared_ptr _data; float _scale; bool _en_lock; + bool _show; dslDial *_vDial; bool _vDialActive; uint8_t _acCoupling; uint8_t _bits; + double _ref_min; + double _ref_max; int _trig_value; double _trig_delta; - double _zero_vrate; - float _hw_offset; + int _zero_offset; + bool _mValid; uint8_t _max; uint8_t _min; double _period; + bool _level_valid; + uint8_t _high; + uint8_t _low; + double _rms; + double _mean; + double _rise_time; + double _fall_time; + double _high_time; + double _burst_time; + uint32_t _pcount; + bool _autoV; bool _autoH; + bool _autoV_over; + uint16_t _auto_cnt; bool _hover_en; uint64_t _hover_index; QPointF _hover_point; - double _hover_value; - - QRect _ms_gear_rect; - QRect _ms_show_rect; - QRect _ms_rect[DSO_MS_END-DSO_MS_BEGIN]; - bool _ms_gear_hover; - bool _ms_show_hover; - bool _ms_show; - bool _ms_en[DSO_MS_END-DSO_MS_BEGIN]; - QString _ms_string[DSO_MS_END-DSO_MS_BEGIN]; + float _hover_value; }; } // namespace view diff --git a/DSView/pv/view/groupsignal.cpp b/DSView/pv/view/groupsignal.cpp old mode 100644 new mode 100755 index 082ce139e746402aa180c44b2aace00d75f890b8..1e67f65413f21b5cd2430111e272f83d657f52a0 --- a/DSView/pv/view/groupsignal.cpp +++ b/DSView/pv/view/groupsignal.cpp @@ -70,8 +70,10 @@ void GroupSignal::set_scale(float scale) _scale = scale; } -void GroupSignal::paint_mid(QPainter &p, int left, int right) +void GroupSignal::paint_mid(QPainter &p, int left, int right, QColor fore, QColor back) { + (void)fore; + (void)back; assert(_data); assert(_view); assert(right >= left); @@ -187,7 +189,7 @@ void GroupSignal::paint_envelope(QPainter &p, delete[] e.samples; } -void GroupSignal::paint_type_options(QPainter &p, int right, const QPoint pt) +void GroupSignal::paint_type_options(QPainter &p, int right, const QPoint pt, QColor fore) { (void)pt; @@ -195,7 +197,7 @@ void GroupSignal::paint_type_options(QPainter &p, int right, const QPoint pt) const QRectF group_index_rect = get_rect(CHNLREG, y, right); QString index_string; int last_index; - p.setPen(QPen(DARK_FORE, 1, Qt::DashLine)); + p.setPen(QPen(fore, 1, Qt::DashLine)); p.drawLine(group_index_rect.bottomLeft(), group_index_rect.bottomRight()); std::list::iterator i = _index_list.begin(); last_index = (*i); @@ -209,7 +211,7 @@ void GroupSignal::paint_type_options(QPainter &p, int right, const QPoint pt) index_string = QString::number((*i)) + "," + index_string; last_index = (*i); } - p.setPen(DARK_FORE); + p.setPen(fore); p.drawText(group_index_rect, Qt::AlignRight | Qt::AlignVCenter, index_string); } diff --git a/DSView/pv/view/groupsignal.h b/DSView/pv/view/groupsignal.h old mode 100644 new mode 100755 index cae5aa8bdb70fe6fa73f767436998f4c3142c32a..358c300f1722a451257cb360a1a43fa4adc0056e --- a/DSView/pv/view/groupsignal.h +++ b/DSView/pv/view/groupsignal.h @@ -74,12 +74,12 @@ public: * @param left the x-coordinate of the left edge of the signal. * @param right the x-coordinate of the right edge of the signal. **/ - void paint_mid(QPainter &p, int left, int right); + void paint_mid(QPainter &p, int left, int right, QColor fore, QColor back); QRectF get_rect(GroupSetRegions type, int y, int right); protected: - void paint_type_options(QPainter &p, int right, const QPoint pt); + void paint_type_options(QPainter &p, int right, const QPoint pt, QColor fore); private: void paint_trace(QPainter &p, diff --git a/DSView/pv/view/header.cpp b/DSView/pv/view/header.cpp old mode 100644 new mode 100755 index 037f62b375a3241c4ac2eb39ff37507ee6dcccd7..bd26d73b9dabc7f90ee14864d14532a18d8307de --- a/DSView/pv/view/header.cpp +++ b/DSView/pv/view/header.cpp @@ -74,6 +74,20 @@ Header::Header(View &parent) : connect(nameEdit, SIGNAL(editingFinished()), this, SLOT(on_action_set_name_triggered())); + + retranslateUi(); +} + +void Header::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + retranslateUi(); + QWidget::changeEvent(event); +} + +void Header::retranslateUi() +{ + update(); } @@ -111,20 +125,19 @@ void Header::paintEvent(QPaintEvent*) QStyleOption o; o.initFrom(this); QPainter painter(this); - //painter.setRenderHint(QPainter::Antialiasing); style()->drawPrimitive(QStyle::PE_Widget, &o, &painter, this); - //painter.begin(this); - const int w = width(); const vector< boost::shared_ptr > traces( _view.get_traces(ALL_VIEW)); const bool dragging = !_drag_traces.empty(); + QColor fore(QWidget::palette().color(QWidget::foregroundRole())); + fore.setAlpha(View::ForeAlpha); BOOST_FOREACH(const boost::shared_ptr t, traces) { assert(t); - t->paint_label(painter, w, dragging ? QPoint(-1, -1) : _mouse_point); + t->paint_label(painter, w, dragging ? QPoint(-1, -1) : _mouse_point, fore); } painter.end(); @@ -303,7 +316,14 @@ void Header::mouseMoveEvent(QMouseEvent *event) _moveFlag = true; traces_moved(); } - } else if (sig->get_type() == SR_CHANNEL_ANALOG) { + } else if (sig->get_type() == SR_CHANNEL_MATH) { + boost::shared_ptr mathTrace; + if ((mathTrace = dynamic_pointer_cast(sig))) { + mathTrace->set_zero_vpos(y); + _moveFlag = true; + traces_moved(); + } + } else if (sig->get_type() == SR_CHANNEL_ANALOG) { boost::shared_ptr analogSig; if ((analogSig = dynamic_pointer_cast(sig))) { analogSig->set_zero_vpos(y); diff --git a/DSView/pv/view/header.h b/DSView/pv/view/header.h old mode 100644 new mode 100755 index 6bad711756f452be733cf91f90331915f1016fa3..7362973a3075bb6a51cb6e0c54f07a5bbd653d6c --- a/DSView/pv/view/header.h +++ b/DSView/pv/view/header.h @@ -52,6 +52,8 @@ private: const QPoint &pt); private: + void changeEvent(QEvent *event); + void retranslateUi(); void paintEvent(QPaintEvent *event); private: diff --git a/DSView/pv/view/lissajoustrace.cpp b/DSView/pv/view/lissajoustrace.cpp new file mode 100755 index 0000000000000000000000000000000000000000..f2c5959c96c8c78e8ffc50231000669aeda04063 --- /dev/null +++ b/DSView/pv/view/lissajoustrace.cpp @@ -0,0 +1,210 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2013 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "../../extdef.h" +#include "lissajoustrace.h" +#include "pv/data/dso.h" +#include "pv/data/dsosnapshot.h" +#include "view.h" +#include "../sigsession.h" +#include "../device/devinst.h" + +#include + +#include +#include + +using namespace boost; +using namespace std; + +namespace pv { +namespace view { + +LissajousTrace::LissajousTrace(bool enable, + boost::shared_ptr data, + int xIndex, int yIndex, int percent): + Trace("Lissajous", xIndex, SR_CHANNEL_LISSAJOUS), + _data(data), + _enable(enable), + _xIndex(xIndex), + _yIndex(yIndex), + _percent(percent) +{ + +} + +LissajousTrace::~LissajousTrace() +{ +} + +bool LissajousTrace::enabled() const +{ + return _enable; +} + +void LissajousTrace::set_enable(bool enable) +{ + _enable = enable; +} + +int LissajousTrace::xIndex() const +{ + return _xIndex; +} + +int LissajousTrace::yIndex() const +{ + return _yIndex; +} + +int LissajousTrace::percent() const +{ + return _percent; +} + +boost::shared_ptr LissajousTrace::get_data() const +{ + return _data; +} + +void LissajousTrace::set_data(boost::shared_ptr data) +{ + _data = data; +} + +int LissajousTrace::rows_size() +{ + return 0; +} + +void LissajousTrace::paint_back(QPainter &p, int left, int right, QColor fore, QColor back) +{ + assert(_view); + + fore.setAlpha(view::View::BackAlpha); + const int height = _viewport->height(); + const int width = right - left; + const int square = min(width, height); + const QPoint leftTop = QPoint(width > square ? (width-square)/2 : 0, + height > square ? (height-square)/2 : 0); + _border = QRect(leftTop.x(), leftTop.y(), square, square); + + QPen solidPen(fore); + solidPen.setStyle(Qt::SolidLine); + p.setPen(solidPen); + p.setBrush(back.black() > 0x80 ? back.darker() : back.lighter()); + p.drawRect(_border); + + QPen dashPen(fore); + dashPen.setStyle(Qt::DashLine); + p.setPen(dashPen); + + const double spanY =square / DIV_NUM; + for (int i = 1; i < DIV_NUM; i++) { + const double posY = _border.top() + spanY * i; + p.drawLine(_border.left(), posY, _border.right(), posY); + } + const double spanX = square / DIV_NUM; + for (int i = 1; i < DIV_NUM; i++) { + const double posX = _border.left() + spanX * i; + p.drawLine(posX, _border.top(), posX, _border.bottom()); + } + + fore.setAlpha(view::View::ForeAlpha); + p.setPen(fore); + p.drawText(_border.marginsRemoved(QMargins(10, 10, 10, 10)), + tr("Lissajous Figure"), Qt::AlignTop | Qt::AlignLeft); + + _view->set_back(true); +} + +void LissajousTrace::paint_mid(QPainter &p, int left, int right, QColor fore, QColor back) +{ + (void)fore; + (void)back; + (void)left; + (void)right; + + assert(_data); + assert(_view); + assert(right >= left); + + if (enabled()) { + const deque< boost::shared_ptr > &snapshots = + _data->get_snapshots(); + if (snapshots.empty()) + return; + const boost::shared_ptr &snapshot = + snapshots.front(); + if (snapshot->empty()) + return; + + int left = _border.left(); + int bottom = _border.bottom(); + double scale = _border.width() / 255.0; + uint64_t sample_count = snapshot->get_sample_count() * min(_percent / 100.0, 1.0); + QPointF *points = new QPointF[sample_count]; + QPointF *point = points; + + int channel_num = snapshot->get_channel_num(); + if (_xIndex >= channel_num || _yIndex >= channel_num) { + p.setPen(view::View::Red); + p.drawText(_border.marginsRemoved(QMargins(10, 30, 10, 30)), + tr("Data source error.")); + } else { + const uint8_t *const samples = snapshot->get_samples(0, sample_count-1, 0); + + for (uint64_t i = 0; i < sample_count; i++) { + *point++ = QPointF(left + samples[i*channel_num + _xIndex] * scale, + bottom - samples[i*channel_num + _yIndex] * scale); + } + p.setPen(view::View::Blue); + //p.drawPoints(points, sample_count); + p.drawPolyline(points, point - points); + delete[] points; + } + } +} + +void LissajousTrace::paint_fore(QPainter &p, int left, int right, QColor fore, QColor back) +{ + (void)p; + (void)left; + (void)right; + (void)fore; + (void)back; + + assert(_view); +} + +void LissajousTrace::paint_label(QPainter &p, int right, const QPoint pt, QColor fore) +{ + (void)p; + (void)right; + (void)pt; + (void)fore; +} + +} // namespace view +} // namespace pv diff --git a/DSView/pv/view/lissajoustrace.h b/DSView/pv/view/lissajoustrace.h new file mode 100755 index 0000000000000000000000000000000000000000..1b5dd2f3086db5a0e825e5e21969179d4097e3d0 --- /dev/null +++ b/DSView/pv/view/lissajoustrace.h @@ -0,0 +1,105 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2013 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef DSVIEW_PV_LISSAJOUSTRACE_H +#define DSVIEW_PV_LISSAJOUSTRACE_H + +#include "trace.h" + +#include + +namespace pv { + +namespace data { +class Logic; +class Dso; +class Analog; +class DsoSnapshot; +} + +namespace view { + +class LissajousTrace : public Trace +{ + Q_OBJECT + +private: + static const int DIV_NUM = 10; + +public: + LissajousTrace(bool enable, + boost::shared_ptr data, + int xIndex, int yIndex, int percent); + + virtual ~LissajousTrace(); + + bool enabled() const; + void set_enable(bool enable); + int xIndex() const; + int yIndex() const; + int percent() const; + + boost::shared_ptr get_data() const; + void set_data(boost::shared_ptr data); + + int rows_size(); + + /** + * Paints the background layer of the trace with a QPainter + * @param p the QPainter to paint into. + * @param left the x-coordinate of the left edge of the signal + * @param right the x-coordinate of the right edge of the signal + **/ + void paint_back(QPainter &p, int left, int right, QColor fore, QColor back); + + /** + * Paints the signal with a QPainter + * @param p the QPainter to paint into. + * @param left the x-coordinate of the left edge of the signal. + * @param right the x-coordinate of the right edge of the signal. + **/ + void paint_mid(QPainter &p, int left, int right, QColor fore, QColor back); + + /** + * Paints the signal with a QPainter + * @param p the QPainter to paint into. + * @param left the x-coordinate of the left edge of the signal. + * @param right the x-coordinate of the right edge of the signal. + **/ + void paint_fore(QPainter &p, int left, int right, QColor fore, QColor back); + + void paint_label(QPainter &p, int right, const QPoint pt, QColor fore); + +private: + boost::shared_ptr _data; + + bool _enable; + int _xIndex; + int _yIndex; + int _percent; + QRect _border; +}; + +} // namespace view +} // namespace pv + +#endif // DSVIEW_PV_LISSAJOUSTRACE_H diff --git a/DSView/pv/view/logicsignal.cpp b/DSView/pv/view/logicsignal.cpp old mode 100644 new mode 100755 index 9a4d152718cc1460456d82fccdf7df098e981f86..95d57b67b72ad53049e4bac7e3b54a55e1ee7bf0 --- a/DSView/pv/view/logicsignal.cpp +++ b/DSView/pv/view/logicsignal.cpp @@ -42,13 +42,6 @@ namespace view { //const float LogicSignal::Oversampling = 2.0f; const float LogicSignal::Oversampling = 1.0f; - -const QColor LogicSignal::EdgeColour(0x80, 0x80, 0x80); -const QColor LogicSignal::HighColour(0x00, 0xC0, 0x00); -const QColor LogicSignal::LowColour(0xC0, 0x00, 0x00); - -const QColor LogicSignal::DEFAULT_COLOR = QColor(150, 150, 150, 255); - const int LogicSignal::StateHeight = 12; const int LogicSignal::StateRound = 5; @@ -59,8 +52,6 @@ LogicSignal::LogicSignal(boost::shared_ptr dev_inst, _data(data), _trig(NONTRIG) { - //_colour = PROBE_COLORS[probe->index % countof(PROBE_COLORS)]; - _colour = DEFAULT_COLOR; } LogicSignal::LogicSignal(boost::shared_ptr s, @@ -128,10 +119,12 @@ bool LogicSignal::commit_trig() } } -void LogicSignal::paint_mid(QPainter &p, int left, int right) +void LogicSignal::paint_mid(QPainter &p, int left, int right, QColor fore, QColor back) { using pv::view::View; + (void)back; + assert(_data); assert(_view); assert(right >= left); @@ -204,7 +197,7 @@ void LogicSignal::paint_mid(QPainter &p, int left, int right) wave_lines.push_back(QLine(preX, preY, x, preY)); } - p.setPen(_colour); + p.setPen(_colour.isValid() ? _colour : fore); p.drawLines(wave_lines.data(), wave_lines.size()); } @@ -231,7 +224,7 @@ void LogicSignal::paint_caps(QPainter &p, QLineF *const lines, p.drawLines(lines, line - lines); } -void LogicSignal::paint_type_options(QPainter &p, int right, const QPoint pt) +void LogicSignal::paint_type_options(QPainter &p, int right, const QPoint pt, QColor fore) { int y = get_y(); const QRectF posTrig_rect = get_rect(POSTRIG, y, right); @@ -241,36 +234,28 @@ void LogicSignal::paint_type_options(QPainter &p, int right, const QPoint pt) const QRectF edgeTrig_rect = get_rect(EDGTRIG, y, right); p.setPen(Qt::NoPen); - p.setBrush(posTrig_rect.contains(pt) ? dsBlue.lighter() : - (_trig == POSTRIG) ? dsBlue : DARK_BACK); + p.setBrush(posTrig_rect.contains(pt) ? View::Blue.lighter() : + (_trig == POSTRIG) ? View::Blue : Qt::transparent); p.drawRect(posTrig_rect); - p.setBrush(higTrig_rect.contains(pt) ? dsBlue.lighter() : - (_trig == HIGTRIG) ? dsBlue : DARK_BACK); + p.setBrush(higTrig_rect.contains(pt) ? View::Blue.lighter() : + (_trig == HIGTRIG) ? View::Blue : Qt::transparent); p.drawRect(higTrig_rect); - p.setBrush(negTrig_rect.contains(pt) ? dsBlue.lighter() : - (_trig == NEGTRIG) ? dsBlue : DARK_BACK); + p.setBrush(negTrig_rect.contains(pt) ? View::Blue.lighter() : + (_trig == NEGTRIG) ? View::Blue : Qt::transparent); p.drawRect(negTrig_rect); - p.setBrush(lowTrig_rect.contains(pt) ? dsBlue.lighter() : - (_trig == LOWTRIG) ? dsBlue : DARK_BACK); + p.setBrush(lowTrig_rect.contains(pt) ? View::Blue.lighter() : + (_trig == LOWTRIG) ? View::Blue : Qt::transparent); p.drawRect(lowTrig_rect); - p.setBrush(edgeTrig_rect.contains(pt) ? dsBlue.lighter() : - (_trig == EDGTRIG) ? dsBlue : DARK_BACK); + p.setBrush(edgeTrig_rect.contains(pt) ? View::Blue.lighter() : + (_trig == EDGTRIG) ? View::Blue : Qt::transparent); p.drawRect(edgeTrig_rect); - p.setPen(QPen(DARK_FORE, 1, Qt::DashLine)); + p.setPen(QPen(fore, 1, Qt::DashLine)); p.setBrush(Qt::transparent); -// p.drawLine(posTrig_rect.right(), posTrig_rect.top(), -// posTrig_rect.right(), posTrig_rect.bottom()); -// p.drawLine(higTrig_rect.right(), higTrig_rect.top(), -// higTrig_rect.right(), higTrig_rect.bottom()); -// p.drawLine(negTrig_rect.right(), negTrig_rect.top(), -// negTrig_rect.right(), negTrig_rect.bottom()); -// p.drawLine(lowTrig_rect.right(), lowTrig_rect.top(), -// lowTrig_rect.right(), lowTrig_rect.bottom()); p.drawLine(posTrig_rect.left(), posTrig_rect.bottom(), edgeTrig_rect.right(), edgeTrig_rect.bottom()); - p.setPen(QPen(DARK_FORE, 2, Qt::SolidLine)); + p.setPen(QPen(fore, 2, Qt::SolidLine)); p.setBrush(Qt::transparent); p.drawLine(posTrig_rect.left() + 5, posTrig_rect.bottom() - 5, posTrig_rect.center().x(), posTrig_rect.bottom() - 5); diff --git a/DSView/pv/view/logicsignal.h b/DSView/pv/view/logicsignal.h old mode 100644 new mode 100755 index 5bdce2daa23c4fe2f8e3abf49bf7ea6fb67abeb4..2cb30d4e099662af588a5fe50443cca0c1636143 --- a/DSView/pv/view/logicsignal.h +++ b/DSView/pv/view/logicsignal.h @@ -41,15 +41,11 @@ namespace view { class LogicSignal : public Signal { + Q_OBJECT + private: static const float Oversampling; - static const QColor EdgeColour; - static const QColor HighColour; - static const QColor LowColour; - - static const QColor DEFAULT_COLOR; - static const int StateHeight; static const int StateRound; @@ -95,7 +91,7 @@ public: * @param left the x-coordinate of the left edge of the signal. * @param right the x-coordinate of the right edge of the signal. **/ - void paint_mid(QPainter &p, int left, int right); + void paint_mid(QPainter &p, int left, int right, QColor fore, QColor back); bool measure(const QPointF &p, uint64_t &index0, uint64_t &index1, uint64_t &index2) const; @@ -112,7 +108,7 @@ public: void paint_mark(QPainter &p, int xstart, int xend, int type); protected: - void paint_type_options(QPainter &p, int right, const QPoint pt); + void paint_type_options(QPainter &p, int right, const QPoint pt, QColor fore); private: diff --git a/DSView/pv/view/mathtrace.cpp b/DSView/pv/view/mathtrace.cpp old mode 100644 new mode 100755 index 2f9fa0850c3f38b2cd890633eac393c9a5bc6a6a..825e4e48a055698d796af00112c73f09a247f8dc --- a/DSView/pv/view/mathtrace.cpp +++ b/DSView/pv/view/mathtrace.cpp @@ -1,7 +1,8 @@ /* - * This file is part of the PulseView project. + * This file is part of the DSView project. + * DSView is based on PulseView. * - * Copyright (C) 2016 DreamSourceLab + * Copyright (C) 2013 DreamSourceLab * * 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 @@ -19,20 +20,22 @@ */ #include -#include #include -#include -#include - +#include "../../extdef.h" #include "mathtrace.h" -#include "../sigsession.h" #include "../data/dso.h" #include "../data/dsosnapshot.h" -#include "../view/dsosignal.h" -#include "../view/viewport.h" -#include "../device/devinst.h" #include "../data/mathstack.h" +#include "view.h" +#include "../sigsession.h" +#include "../device/devinst.h" +#include "../view/dsosignal.h" + +#include + +#include +#include using namespace boost; using namespace std; @@ -40,57 +43,33 @@ using namespace std; namespace pv { namespace view { -const int MathTrace::UpMargin = 0; -const int MathTrace::DownMargin = 0; -const int MathTrace::RightMargin = 30; -const QString MathTrace::FFT_ViewMode[2] = { - "Linear RMS", - "DBV RMS" -}; - -const QString MathTrace::FreqPrefixes[9] = - {"", "", "", "", "K", "M", "G", "T", "P"}; -const int MathTrace::FirstSIPrefixPower = -9; -const int MathTrace::LastSIPrefixPower = 15; -const int MathTrace::Pricision = 2; -const int MathTrace::FreqMinorDivNum = 10; -const int MathTrace::TickHeight = 15; -const int MathTrace::VolDivNum = 5; - -const int MathTrace::DbvRanges[4] = { - 100, - 120, - 150, - 200, -}; - -const int MathTrace::HoverPointSize = 3; -const double MathTrace::VerticalRate = 1.0 / 2000.0; - -MathTrace::MathTrace(pv::SigSession &session, - boost::shared_ptr math_stack, int index) : - Trace("FFT("+QString::number(index)+")", index, SR_CHANNEL_FFT), - _session(session), +MathTrace::MathTrace(bool enable, + boost::shared_ptr math_stack, + boost::shared_ptr dsoSig1, + boost::shared_ptr dsoSig2): + Trace("M", dsoSig1->get_index(), SR_CHANNEL_MATH), _math_stack(math_stack), - _enable(false), - _view_mode(0), + _dsoSig1(dsoSig1), + _dsoSig2(dsoSig2), + _enable(enable), + _show(true), + _scale(0), + _zero_vrate(0.5), + _hw_offset(0x80), _hover_en(false), - _scale(1), - _offset(0) -{ - _typeWidth = 0; - const vector< boost::shared_ptr > sigs(_session.get_signals()); - for(size_t i = 0; i < sigs.size(); i++) { - const boost::shared_ptr s(sigs[i]); - assert(s); - if (dynamic_pointer_cast(s) && index == s->get_index()) - _colour = s->get_colour(); - } + _hover_index(0), + _hover_point(QPointF(0, 0)), + _hover_voltage(0) +{ + _vDial = _math_stack->get_vDial(); + update_vDial(); + _colour = View::Red; + _ref_min = dsoSig1->get_ref_min(); + _ref_max = dsoSig1->get_ref_max(); } MathTrace::~MathTrace() { - } bool MathTrace::enabled() const @@ -103,385 +82,436 @@ void MathTrace::set_enable(bool enable) _enable = enable; } -int MathTrace::view_mode() const +int MathTrace::src1() const { - return _view_mode; + return _dsoSig1->get_index(); } -void MathTrace::set_view_mode(unsigned int mode) +int MathTrace::src2() const { - assert(mode < sizeof(FFT_ViewMode)/sizeof(FFT_ViewMode[0])); - _view_mode = mode; + return _dsoSig2->get_index(); } -std::vector MathTrace::get_view_modes_support() +float MathTrace::get_scale() { - std::vector modes; - for (unsigned int i = 0; i < sizeof(FFT_ViewMode)/sizeof(FFT_ViewMode[0]); i++) { - modes.push_back(FFT_ViewMode[i]); - } - return modes; + return _scale; } -const boost::shared_ptr& MathTrace::get_math_stack() const +int MathTrace::get_name_width() const { - return _math_stack; + return 0; } -void MathTrace::init_zoom() +void MathTrace::update_vDial() { - _scale = 1; - _offset = 0; + _vDial->set_value(_math_stack->default_vDialValue()); } -void MathTrace::zoom(double steps, int offset) +void MathTrace::go_vDialPre() { - if (!_view) - return; + if (enabled() && !_vDial->isMin()) { + if (_view->session().get_capture_state() == SigSession::Running) + _view->session().refresh(DsoSignal::RefreshShort); + const double pre_vdiv = _vDial->get_value(); + _vDial->set_sel(_vDial->get_sel() - 1); - const int width = get_view_rect().width(); - double pre_offset = _offset + _scale*offset/width; - _scale *= std::pow(3.0/2.0, -steps); - _scale = max(min(_scale, 1.0), 100.0/_math_stack->get_sample_num()); - _offset = pre_offset - _scale*offset/width; - _offset = max(min(_offset, 1-_scale), 0.0); + if (_view->session().get_capture_state() == SigSession::Stopped) + _scale *= pre_vdiv/_vDial->get_value(); - _view->set_update(_viewport, true); - _view->update(); + _view->set_update(_viewport, true); + _view->update(); + } } -void MathTrace::set_offset(double delta) +void MathTrace::go_vDialNext() { - int width = get_view_rect().width(); - _offset = _offset + (delta*_scale / width); - _offset = max(min(_offset, 1-_scale), 0.0); + if (enabled() && !_vDial->isMax()) { + if (_view->session().get_capture_state() == SigSession::Running) + _view->session().refresh(DsoSignal::RefreshShort); + const double pre_vdiv = _vDial->get_value(); + _vDial->set_sel(_vDial->get_sel() + 1); - _view->set_update(_viewport, true); - _view->update(); + if (_view->session().get_capture_state() == SigSession::Stopped) + _scale *= pre_vdiv/_vDial->get_value(); + + _view->set_update(_viewport, true); + _view->update(); + } } -double MathTrace::get_offset() const +uint64_t MathTrace::get_vDialValue() const { - return _offset; + return _vDial->get_value(); } -void MathTrace::set_scale(double scale) +uint16_t MathTrace::get_vDialSel() const { - _scale = max(min(scale, 1.0), 100.0/_math_stack->get_sample_num()); - - _view->set_update(_viewport, true); - _view->update(); + return _vDial->get_sel(); } -double MathTrace::get_scale() const +double MathTrace::get_zero_ratio() { - return _scale; + return _zero_vrate; } -void MathTrace::set_dbv_range(int range) +void MathTrace::set_zero_vrate(double rate) { - _dbv_range = range; + _zero_vrate = rate; + _hw_offset = _zero_vrate * (_ref_max - _ref_min) + _ref_min; } -int MathTrace::dbv_range() const +int MathTrace::get_zero_vpos() const { - return _dbv_range; + return _zero_vrate * get_view_rect().height() + DsoSignal::UpMargin; } -std::vector MathTrace::get_dbv_ranges() +void MathTrace::set_zero_vpos(int pos) { - std::vector range; - for (unsigned int i = 0; i < sizeof(DbvRanges)/sizeof(DbvRanges[0]); i++) { - range.push_back(DbvRanges[i]); + if (enabled()) { + set_zero_vrate(min(max(pos - DsoSignal::UpMargin, 0), + get_view_rect().height()) * 1.0 / get_view_rect().height()); } - return range; } -QString MathTrace::format_freq(double freq, unsigned precision) +void MathTrace::set_show(bool show) { - if (freq <= 0) { - return "0Hz"; - } else { - const int order = floor(log10f(freq)); - assert(order >= FirstSIPrefixPower); - assert(order <= LastSIPrefixPower); - const int prefix = floor((order - FirstSIPrefixPower)/ 3.0f); - const double divider = pow(10.0, max(prefix * 3.0 + FirstSIPrefixPower, 0.0)); - - QString s; - QTextStream ts(&s); - ts.setRealNumberPrecision(precision); - ts << fixed << freq / divider << - FreqPrefixes[prefix] << "Hz"; - return s; - } + _show = show; } -bool MathTrace::measure(const QPoint &p) +QRect MathTrace::get_view_rect() const { - _hover_en = false; - if(!_view || !enabled()) - return false; + assert(_viewport); + return QRect(0, DsoSignal::UpMargin, + _viewport->width() - DsoSignal::RightMargin, + _viewport->height() - DsoSignal::UpMargin - DsoSignal::DownMargin); +} - const QRect window = get_view_rect(); - if (!window.contains(p)) - return false; +void MathTrace::paint_back(QPainter &p, int left, int right, QColor fore, QColor back) +{ + (void)p; + (void)left; + (void)right; + (void)fore; + (void)back; +} - const std::vector samples(_math_stack->get_fft_spectrum()); - if(samples.empty()) - return false; +void MathTrace::paint_mid(QPainter &p, int left, int right, QColor fore, QColor back) +{ + (void)fore; + (void)back; - const unsigned int full_size = (_math_stack->get_sample_num()/2); - const double view_off = full_size * _offset; - const double view_size = full_size*_scale; - const double sample_per_pixels = view_size/window.width(); - _hover_index = std::round(p.x() * sample_per_pixels + view_off); + if (!_show) + return; - if (_hover_index < full_size) - _hover_en = true; + assert(_math_stack); + assert(_view); + assert(right >= left); - //_view->set_update(_viewport, true); - _view->update(); - return true; + if (enabled()) { + const float top = get_view_rect().top(); + const int height = get_view_rect().height(); + const int width = right - left; + const float zeroY = _zero_vrate * height + top; + + const double scale = _view->scale(); + assert(scale > 0); + const int64_t offset = _view->offset(); + + const double pixels_offset = offset; + const double samplerate = _view->session().cur_samplerate(); + const int64_t last_sample = max((int64_t)(_math_stack->get_sample_num() - 1), (int64_t)0); + const double samples_per_pixel = samplerate * scale; + const double start = offset * samples_per_pixel; + const double end = start + samples_per_pixel * width; + + const int64_t start_sample = min(max((int64_t)floor(start), + (int64_t)0), last_sample); + const int64_t end_sample = min(max((int64_t)ceil(end) + 1, + (int64_t)0), last_sample); + + _scale = get_view_rect().height() * _math_stack->get_math_scale() * 1000.0 / get_vDialValue(); + + if (samples_per_pixel < DsoSignal::EnvelopeThreshold) { + _math_stack->enable_envelope(false); + paint_trace(p, zeroY, left, + start_sample, end_sample, + pixels_offset, samples_per_pixel); + } else { + _math_stack->enable_envelope(true); + paint_envelope(p, zeroY, left, + start_sample, end_sample, + pixels_offset, samples_per_pixel); + } + } } - -void MathTrace::paint_back(QPainter &p, int left, int right) +void MathTrace::paint_fore(QPainter &p, int left, int right, QColor fore, QColor back) { - if(!_view) + if (!_show) return; - const int height = get_view_rect().height(); - const int width = right - left; + assert(_view); + + fore.setAlpha(View::BackAlpha); + QPen pen(fore); + pen.setStyle(Qt::DotLine); + p.setPen(pen); + p.drawLine(left, get_zero_vpos(), right, get_zero_vpos()); - QPen solidPen(Signal::dsFore); - solidPen.setStyle(Qt::SolidLine); - p.setPen(solidPen); - p.setBrush(Trace::dsBack); - p.drawRect(left, UpMargin, width, height); + // Paint measure + fore.setAlpha(View::ForeAlpha); + if (_view->session().get_capture_state() == SigSession::Stopped) + paint_hover_measure(p, fore, back); } -void MathTrace::paint_mid(QPainter &p, int left, int right) +void MathTrace::paint_trace(QPainter &p, + int zeroY, int left, const int64_t start, const int64_t end, + const double pixels_offset, const double samples_per_pixel) { - if(!_view) - return; - assert(right >= left); - - if (enabled()) { - const std::vector samples(_math_stack->get_fft_spectrum()); - if(samples.empty()) - return; + const int64_t sample_count = end - start + 1; + if (sample_count > 0) { QColor trace_colour = _colour; - trace_colour.setAlpha(150); + trace_colour.setAlpha(View::ForeAlpha); p.setPen(trace_colour); - const int full_size = (_math_stack->get_sample_num()/2); - const double view_off = full_size * _offset; - const int view_start = floor(view_off); - const int view_size = full_size*_scale; - QPointF *points = new QPointF[samples.size()]; - QPointF *point = points; + if ((uint64_t)end >= _math_stack->get_sample_num()) + return; - const bool dc_ignored = _math_stack->dc_ignored(); - const double height = get_view_rect().height(); - const double width = right - left; - const double pixels_per_sample = width/view_size; - - double vdiv = 0; - double vfactor = 0; - BOOST_FOREACH(const boost::shared_ptr s, _session.get_signals()) { - boost::shared_ptr dsoSig; - if ((dsoSig = dynamic_pointer_cast(s))) { - if(dsoSig->get_index() == _math_stack->get_index()) { - vdiv = dsoSig->get_vDialValue(); - vfactor = dsoSig->get_factor(); - break; - } - } - } - if (_view_mode == 0) { - _vmin = 0; - _vmax = (vdiv*DS_CONF_DSO_HDIVS*vfactor)*VerticalRate; - } else { - _vmax = 20*log10((vdiv*DS_CONF_DSO_HDIVS*vfactor)*VerticalRate); - _vmin = _vmax - _dbv_range; - } + const double *const values = _math_stack->get_math(start); + assert(values); - //const double max_value = *std::max_element(dc_ignored ? ++samples.begin() : samples.begin(), samples.end()); - //const double min_value = *std::min_element(dc_ignored ? ++samples.begin() : samples.begin(), samples.end()); - //_vmax = (_view_mode == 0) ? max_value : 20*log10(max_value); - //_vmin = (_view_mode == 0) ? min_value : 20*log10(min_value); - const double scale = height / (_vmax - _vmin); + QPointF *points = new QPointF[sample_count]; + QPointF *point = points; + + double top = get_view_rect().top(); + double bottom = get_view_rect().bottom(); + float x = (start / samples_per_pixel - pixels_offset) + left; + double pixels_per_sample = 1.0/samples_per_pixel; - double x = (view_start-view_off)*pixels_per_sample; - uint64_t sample = view_start; - if (dc_ignored && sample == 0) { - sample++; + for (int64_t index = 0; index < sample_count; index++) { + *point++ = QPointF(x, min(max(top, zeroY - (values[index] * _scale)), bottom)); x += pixels_per_sample; } - double min_mag = pow(10.0, _vmin/20); - do{ - double mag = samples[sample]; - if (_view_mode != 0) { - if (mag < min_mag) - mag = _vmin; - else - mag = 20*log10(mag); - } - const double y = height - (scale * (mag - _vmin)); - *point++ = QPointF(x, y); - x += pixels_per_sample; - sample++; - }while(xviewport()->width() - get_view_rect().width(), get_view_rect().height()); + delete[] points; } } -void MathTrace::paint_fore(QPainter &p, int left, int right) +void MathTrace::paint_envelope(QPainter &p, + int zeroY, int left, const int64_t start, const int64_t end, + const double pixels_offset, const double samples_per_pixel) { - using namespace Qt; + using namespace Qt; + + data::MathStack::EnvelopeSection e; + _math_stack->get_math_envelope_section(e, start, end, samples_per_pixel); + + if (e.length < 2) + return; + + p.setPen(QPen(NoPen)); + QColor envelope_colour = _colour; + envelope_colour.setAlpha(View::ForeAlpha); + p.setBrush(envelope_colour); + + QRectF *const rects = new QRectF[e.length]; + QRectF *rect = rects; + double top = get_view_rect().top(); + double bottom = get_view_rect().bottom(); + for(uint64_t sample = 0; sample < e.length-1; sample++) { + const float x = ((e.scale * sample + e.start) / + samples_per_pixel - pixels_offset) + left; + const data::MathStack::EnvelopeSample *const s = + e.samples + sample; + + // We overlap this sample with the next so that vertical + // gaps do not appear during steep rising or falling edges + const float b = min(max(top, zeroY - max(s->max, (s+1)->min) * _scale), bottom); + const float t = min(max(top, zeroY - min(s->min, (s+1)->max) * _scale), bottom); + + float h = b - t; + if(h >= 0.0f && h <= 1.0f) + h = 1.0f; + if(h <= 0.0f && h >= -1.0f) + h = -1.0f; + + *rect++ = QRectF(x, t, 1.0f, h); + } + + p.drawRects(rects, e.length); + + delete[] rects; +} - if(!_view) - return; - assert(right >= left); +void MathTrace::paint_type_options(QPainter &p, int right, const QPoint pt, QColor fore) +{ + p.setRenderHint(QPainter::Antialiasing, true); - (void)left; + QColor foreBack = fore; + foreBack.setAlpha(View::BackAlpha); + int y = get_y(); + const QRectF vDial_rect = get_rect(DSO_VDIAL, y, right); + + QString pText; + _vDial->paint(p, vDial_rect, _colour, pt, pText); + QFontMetrics fm(p.font()); + const QRectF valueRect = QRectF(0, vDial_rect.top()-fm.height()-10, right, fm.height()); + p.drawText(valueRect, Qt::AlignCenter, pText); + + p.setRenderHint(QPainter::Antialiasing, false); +} + +bool MathTrace::mouse_wheel(int right, const QPoint pt, const int shift) +{ + int y = get_y(); + const QRectF vDial_rect = get_rect(DSO_VDIAL, y, right); + + if (vDial_rect.contains(pt)) { + if (shift > 0.5) + go_vDialPre(); + else if (shift < -0.5) + go_vDialNext(); + return true; + } else { + return false; + } + + return true; +} + +QRectF MathTrace::get_rect(MathSetRegions type, int y, int right) +{ (void)right; - const int text_height = p.boundingRect(0, 0, INT_MAX, INT_MAX, - AlignLeft | AlignTop, "8").height(); - const double width = get_view_rect().width(); - const double height = get_view_rect().height(); - double blank_top = 0; - double blank_right = width; - - // horizontal ruler - const double NyFreq = _session.cur_samplerate() / (2.0 * _math_stack->get_sample_interval()); - const double deltaFreq = _session.cur_samplerate() * 1.0 / - (_math_stack->get_sample_num() * _math_stack->get_sample_interval()); - const double FreqRange = NyFreq * _scale; - const double FreqOffset = NyFreq * _offset; - - const int order = (int)floor(log10(FreqRange)); - const double multiplier = (pow(10.0, order) == FreqRange) ? FreqRange/10 : pow(10.0, order); - const double freq_per_pixel = FreqRange / width; - - p.setPen(Trace::DARK_FORE); - p.setBrush(Qt::NoBrush); - double tick_freq = multiplier * (int)floor(FreqOffset / multiplier); - int division = (int)round(tick_freq * FreqMinorDivNum / multiplier); - double x = (tick_freq - FreqOffset) / freq_per_pixel; - do{ - if (division%FreqMinorDivNum == 0) { - QString freq_str = format_freq(tick_freq); - double typical_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, - AlignLeft | AlignTop, freq_str).width() + 10; - p.drawLine(x, 1, x, TickHeight); - if (x > typical_width/2 && (width-x) > typical_width/2) - p.drawText(x-typical_width/2, TickHeight, typical_width, text_height, - AlignCenter | AlignTop | TextDontClip, freq_str); - } else { - p.drawLine(x, 1, x, TickHeight/2); - } - tick_freq += multiplier/FreqMinorDivNum; - division++; - x = (tick_freq - FreqOffset) / freq_per_pixel; - } while(x < width); - blank_top = max(blank_top, (double)TickHeight + text_height); - - // delta Frequency - QString freq_str = QString::fromWCharArray(L" \u0394") + "Freq: " + format_freq(deltaFreq,4); - p.drawText(0, 0, width, get_view_rect().height(), - AlignRight | AlignBottom | TextDontClip, freq_str); - double delta_left = width-p.boundingRect(0, 0, INT_MAX, INT_MAX, - AlignLeft | AlignTop, freq_str).width(); - blank_right = min(delta_left, blank_right); - - // Vertical ruler - const double vRange = _vmax - _vmin; - const double vOffset = _vmin; - const double vol_per_tick = vRange / VolDivNum; - - p.setPen(Trace::DARK_FORE); - p.setBrush(Qt::NoBrush); - double tick_vol = vol_per_tick + vOffset; - double y = height - height / VolDivNum; - const QString unit = (_view_mode == 0) ? "" : "dbv"; - do{ - if (y > text_height && y < (height - text_height)) { - QString vol_str = QString::number(tick_vol, 'f', Pricision) + unit; - double vol_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, - AlignLeft | AlignTop, vol_str).width(); - p.drawLine(width, y, width-TickHeight/2, y); - p.drawText(width-TickHeight-vol_width, y-text_height/2, vol_width, text_height, - AlignCenter | AlignTop | TextDontClip, vol_str); - blank_right = min(width-TickHeight-vol_width, blank_right); - } - tick_vol += vol_per_tick; - y -= height / VolDivNum; - } while(y > 0); + if (type == DSO_VDIAL) + return QRectF( + get_leftWidth() + SquareWidth*0.5 + Margin, + y - SquareWidth * SquareNum + SquareWidth * 3, + SquareWidth * (SquareNum-1), SquareWidth * (SquareNum-1)); + else + return QRectF(0, 0, 0, 0); +} + +void MathTrace::paint_hover_measure(QPainter &p, QColor fore, QColor back) +{ // Hover measure if (_hover_en) { - const std::vector samples(_math_stack->get_fft_spectrum()); - if(samples.empty()) - return; - const int full_size = (_math_stack->get_sample_num()/2); - const double view_off = full_size * _offset; - const int view_size = full_size*_scale; - const double scale = height / (_vmax - _vmin); - const double pixels_per_sample = width/view_size; - double x = (_hover_index-view_off)*pixels_per_sample; - double min_mag = pow(10.0, _vmin/20); - _hover_value = samples[_hover_index]; - if (_view_mode != 0) { - if (_hover_value < min_mag) - _hover_value = _vmin; - else - _hover_value = 20*log10(_hover_value); - } - const double y = height - (scale * (_hover_value - _vmin)); - _hover_point = QPointF(x, y); - - p.setPen(QPen(Trace::DARK_FORE, 1, Qt::DashLine)); - p.setBrush(Qt::NoBrush); - p.drawLine(_hover_point.x(), 0, _hover_point.x(), height); - - QString hover_str = QString::number(_hover_value, 'f', 4) + unit + "@" + format_freq(deltaFreq * _hover_index, 4); + QString hover_str = get_voltage(_hover_voltage, 2); const int hover_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, - AlignLeft | AlignTop, hover_str).width(); + Qt::AlignLeft | Qt::AlignTop, hover_str).width() + 10; const int hover_height = p.boundingRect(0, 0, INT_MAX, INT_MAX, - AlignLeft | AlignTop, hover_str).height(); - QRectF hover_rect(_hover_point.x(), _hover_point.y()-hover_height, hover_width, hover_height); - if (hover_rect.right() > blank_right) - hover_rect.moveRight(min(_hover_point.x(), blank_right)); - if (hover_rect.top() < blank_top) - hover_rect.moveTop(max(_hover_point.y(), blank_top)); - if (hover_rect.top() > 0) - p.drawText(hover_rect, AlignCenter | AlignTop | TextDontClip, hover_str); - - p.setPen(Qt::NoPen); - p.setBrush(Trace::DARK_FORE); - p.drawEllipse(_hover_point, HoverPointSize, HoverPointSize); + Qt::AlignLeft | Qt::AlignTop, hover_str).height(); + QRectF hover_rect(_hover_point.x(), _hover_point.y()-hover_height/2, hover_width, hover_height); + if (hover_rect.right() > get_view_rect().right()) + hover_rect.moveRight(_hover_point.x()); + if (hover_rect.top() < get_view_rect().top()) + hover_rect.moveTop(_hover_point.y()); + if (hover_rect.bottom() > get_view_rect().bottom()) + hover_rect.moveBottom(_hover_point.y()); + + p.setPen(fore); + p.setBrush(back); + p.drawRect(_hover_point.x()-1, _hover_point.y()-1, + DsoSignal::HoverPointSize, DsoSignal::HoverPointSize); + p.drawText(hover_rect, Qt::AlignCenter | Qt::AlignTop | Qt::TextDontClip, hover_str); + } + + list::iterator i = _view->get_cursorList().begin(); + while (i != _view->get_cursorList().end()) { + float pt_value; + const QPointF pt = get_point((*i)->index(), pt_value); + QString pt_str = get_voltage(pt_value, 2); + const int pt_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, + Qt::AlignLeft | Qt::AlignTop, pt_str).width() + 10; + const int pt_height = p.boundingRect(0, 0, INT_MAX, INT_MAX, + Qt::AlignLeft | Qt::AlignTop, pt_str).height(); + QRectF pt_rect(pt.x(), pt.y()-pt_height/2, pt_width, pt_height); + if (pt_rect.right() > get_view_rect().right()) + pt_rect.moveRight(pt.x()); + if (pt_rect.top() < get_view_rect().top()) + pt_rect.moveTop(pt.y()); + if (pt_rect.bottom() > get_view_rect().bottom()) + pt_rect.moveBottom(pt.y()); + + p.drawRect(pt.x()-1, pt.y()-1, 2, 2); + p.drawLine(pt.x()-2, pt.y()-2, pt.x()+2, pt.y()+2); + p.drawLine(pt.x()+2, pt.y()-2, pt.x()-2, pt.y()+2); + p.drawText(pt_rect, Qt::AlignCenter | Qt::AlignTop | Qt::TextDontClip, pt_str); + + i++; } } -void MathTrace::paint_type_options(QPainter &p, int right, const QPoint pt) +bool MathTrace::measure(const QPointF &p) { - (void)p; - (void)pt; - (void)right; + _hover_en = false; + if (!enabled()) + return false; + + const QRectF window = get_view_rect(); + if (!window.contains(p)) + return false; + + const double scale = _view->scale(); + assert(scale > 0); + const int64_t pixels_offset = _view->offset(); + const double samplerate = _view->session().cur_samplerate(); + const double samples_per_pixel = samplerate * scale; + + _hover_index = floor((p.x() + pixels_offset) * samples_per_pixel+0.5); + if (_hover_index >= _math_stack->get_sample_num()) + return false; + + _hover_point = get_point(_hover_index, _hover_voltage); + _hover_en = true; + return true; } -QRect MathTrace::get_view_rect() const +QPointF MathTrace::get_point(uint64_t index, float &value) { - assert(_viewport); - return QRect(0, UpMargin, - _viewport->width() - RightMargin, - _viewport->height() - UpMargin - DownMargin); + QPointF pt = QPointF(0, 0); + + const double scale = _view->scale(); + assert(scale > 0); + const int64_t pixels_offset = _view->offset(); + const double samplerate = _view->session().cur_samplerate(); + const double samples_per_pixel = samplerate * scale; + + const float top = get_view_rect().top(); + const float bottom = get_view_rect().bottom(); + const float zeroP = _zero_vrate * get_view_rect().height() + top; + const float x = (index / samples_per_pixel - pixels_offset); + + value = *_math_stack->get_math(index); + float y = min(max(top, zeroP - (value * _scale)), bottom); + pt = QPointF(x, y); + return pt; +} + +QString MathTrace::get_voltage(double v, int p) +{ + return abs(v) >= 1 ? QString::number(v, 'f', p) + _math_stack->get_unit(1) : + QString::number(v * 1000, 'f', p) + _math_stack->get_unit(0); +} + +QString MathTrace::get_time(double t) +{ + QString str = (abs(t) > 1000000000 ? QString::number(t/1000000000, 'f', 2) + "S" : + abs(t) > 1000000 ? QString::number(t/1000000, 'f', 2) + "mS" : + abs(t) > 1000 ? QString::number(t/1000, 'f', 2) + "uS" : QString::number(t, 'f', 2) + "nS"); + return str; } +const boost::shared_ptr& MathTrace::get_math_stack() const +{ + return _math_stack; +} + + } // namespace view } // namespace pv diff --git a/DSView/pv/view/mathtrace.h b/DSView/pv/view/mathtrace.h old mode 100644 new mode 100755 index 99786f445d0fb4f782a91c36dcdd5398380001f8..3bcd9428c0b6a751fa92120fd59345f6a5c8e3af --- a/DSView/pv/view/mathtrace.h +++ b/DSView/pv/view/mathtrace.h @@ -1,7 +1,8 @@ /* - * This file is part of the PulseView project. + * This file is part of the DSView project. + * DSView is based on PulseView. * - * Copyright (C) 2016 DreamSourceLab + * Copyright (C) 2013 DreamSourceLab * * 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 @@ -18,139 +19,156 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef DSVIEW_PV_VIEW_MATHTRACE_H -#define DSVIEW_PV_VIEW_MATHTRACE_H -#include "trace.h" +#ifndef DSVIEW_PV_MATHTRACE_H +#define DSVIEW_PV_MATHTRACE_H -#include -#include +#include "trace.h" #include -struct srd_channel; - namespace pv { -class SigSession; - -namespace data{ +namespace data { +class Logic; +class Dso; +class Analog; +class DsoSnapshot; class MathStack; } namespace view { +class DsoSignal; + class MathTrace : public Trace { Q_OBJECT -private: - static const int UpMargin; - static const int DownMargin; - static const int RightMargin; - static const QString FFT_ViewMode[2]; +public: + enum MathSetRegions { + DSO_NONE = -1, + DSO_VDIAL, + }; - static const QString FreqPrefixes[9]; - static const int FirstSIPrefixPower; - static const int LastSIPrefixPower; - static const int Pricision; - static const int FreqMinorDivNum; - static const int TickHeight; - static const int VolDivNum; +public: + MathTrace(bool enable, boost::shared_ptr math_stack, + boost::shared_ptr dsoSig1, + boost::shared_ptr dsoSig2); - static const int DbvRanges[4]; + virtual ~MathTrace(); - static const int HoverPointSize; + float get_scale(); - static const double VerticalRate; + int get_name_width() const; -public: - MathTrace(pv::SigSession &session, - boost::shared_ptr math_stack, int index); - ~MathTrace(); + /** + * + */ + void update_vDial(); + void go_vDialPre(); + void go_vDialNext(); + uint64_t get_vDialValue() const; + uint16_t get_vDialSel() const; bool enabled() const; void set_enable(bool enable); + void set_show(bool show); - void init_zoom(); - void zoom(double steps, int offset); - bool zoom_hit() const; - void set_zoom_hit(bool hit); - - void set_offset(double delta); - double get_offset() const; + int get_zero_vpos() const; + void set_zero_vpos(int pos); - void set_scale(double scale); - double get_scale() const; + int src1() const; + int src2() const; - void set_dbv_range(int range); - int dbv_range() const; - std::vector get_dbv_ranges(); + /** + * + */ + bool measure(const QPointF &p); + QPointF get_point(uint64_t index, float &value); - int view_mode() const; - void set_view_mode(unsigned int mode); - std::vector get_view_modes_support(); - const boost::shared_ptr& get_math_stack() const; + /** + * Gets the mid-Y position of this signal. + */ + double get_zero_ratio(); - static QString format_freq(double freq, unsigned precision = Pricision); + /** + * Sets the mid-Y position of this signal. + */ + void set_zero_vrate(double rate); - bool measure(const QPoint &p); + QString get_voltage(double v, int p); + QString get_time(double t); /** * Paints the background layer of the trace with a QPainter * @param p the QPainter to paint into. - * @param left the x-coordinate of the left edge of the signal. - * @param right the x-coordinate of the right edge of the signal. - **/ - void paint_back(QPainter &p, int left, int right); - - /** - * Paints the mid-layer of the trace with a QPainter - * @param p the QPainter to paint into. * @param left the x-coordinate of the left edge of the signal * @param right the x-coordinate of the right edge of the signal **/ - void paint_mid(QPainter &p, int left, int right); + void paint_back(QPainter &p, int left, int right, QColor fore, QColor back); + + /** + * Paints the signal with a QPainter + * @param p the QPainter to paint into. + * @param left the x-coordinate of the left edge of the signal. + * @param right the x-coordinate of the right edge of the signal. + **/ + void paint_mid(QPainter &p, int left, int right, QColor fore, QColor back); /** - * Paints the foreground layer of the trace with a QPainter + * Paints the signal with a QPainter * @param p the QPainter to paint into. - * @param left the x-coordinate of the left edge of the signal - * @param right the x-coordinate of the right edge of the signal + * @param left the x-coordinate of the left edge of the signal. + * @param right the x-coordinate of the right edge of the signal. **/ - void paint_fore(QPainter &p, int left, int right); + void paint_fore(QPainter &p, int left, int right, QColor fore, QColor back); QRect get_view_rect() const; + QRectF get_rect(MathSetRegions type, int y, int right); + + bool mouse_wheel(int right, const QPoint pt, const int shift); + + const boost::shared_ptr& get_math_stack() const; + protected: - void paint_type_options(QPainter &p, int right, const QPoint pt); + void paint_type_options(QPainter &p, int right, const QPoint pt, QColor fore); private: + void paint_trace(QPainter &p, + int zeroY, int left, const int64_t start, const int64_t end, + const double pixels_offset, const double samples_per_pixel); -private slots: + void paint_envelope(QPainter &p, + int zeroY, int left, const int64_t start, const int64_t end, + const double pixels_offset, const double samples_per_pixel); + + void paint_hover_measure(QPainter &p, QColor fore, QColor back); private: - pv::SigSession &_session; boost::shared_ptr _math_stack; - + boost::shared_ptr _dsoSig1; + boost::shared_ptr _dsoSig2; bool _enable; - int _view_mode; + bool _show; - double _vmax; - double _vmin; - int _dbv_range; + dslDial *_vDial; + double _ref_min; + double _ref_max; + float _scale; + + double _zero_vrate; + float _hw_offset; - uint64_t _hover_index; bool _hover_en; + uint64_t _hover_index; QPointF _hover_point; - double _hover_value; - - double _scale; - double _offset; + float _hover_voltage; }; } // namespace view } // namespace pv -#endif // DSVIEW_PV_VIEW_FFTTRACE_H +#endif // DSVIEW_PV_MATHTRACE_H diff --git a/DSView/pv/view/ruler.cpp b/DSView/pv/view/ruler.cpp old mode 100644 new mode 100755 index d42fc1b43899ff9c4b944eb605197b14966a9529..9de9a26d961f478023d6002ddb54996c690f5512 --- a/DSView/pv/view/ruler.cpp +++ b/DSView/pv/view/ruler.cpp @@ -59,7 +59,7 @@ const QString Ruler::FreqPrefixes[9] = const int Ruler::FirstSIPrefixPower = -15; const int Ruler::pricision = 2; -const int Ruler::HoverArrowSize = 5; +const int Ruler::HoverArrowSize = 4; const int Ruler::CursorSelWidth = 20; const QColor Ruler::CursorColor[8] = @@ -72,15 +72,6 @@ const QColor Ruler::CursorColor[8] = QColor(231, 126, 34, 200), QColor(232, 76, 61, 200)}; -const QColor Ruler::dsBlue = QColor(17, 133, 209, 255); -const QColor Ruler::dsYellow = QColor(238, 178, 17, 255); -const QColor Ruler::dsRed = QColor(213, 15, 37, 255); -const QColor Ruler::dsGreen = QColor(0, 153, 37, 255); -const QColor Ruler::RULER_COLOR = QColor(255, 255, 255, 255); - -const QColor Ruler::HitColor = dsYellow; -const QColor Ruler::WarnColor = dsRed; - Ruler::Ruler(View &parent) : QWidget(&parent), _view(parent), @@ -183,14 +174,10 @@ void Ruler::paintEvent(QPaintEvent*) QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &o, &p, this); - //p.begin(this); - //QPainter p(this); - //p.setRenderHint(QPainter::Antialiasing); - // Draw tick mark draw_logic_tick_mark(p); - p.setRenderHint(QPainter::Antialiasing); + p.setRenderHint(QPainter::Antialiasing, true); // Draw the hover mark draw_hover_mark(p); @@ -335,105 +322,6 @@ void Ruler::mouseReleaseEvent(QMouseEvent *event) } } -void Ruler::draw_tick_mark(QPainter &p) -{ - using namespace Qt; - - const double SpacingIncrement = 32.0; - const double MinValueSpacing = 16.0; - const int ValueMargin = 15; - - double min_width = SpacingIncrement, typical_width; - double tick_period; - unsigned int prefix; - - // Find tick spacing, and number formatting that does not cause - // value to collide. - do - { - _min_period = _view.scale() * min_width; - - //const int order = (int)floorf(log10f(_min_period)); - const int order = ceil(log10f(_min_period)); - const double order_decimal = pow(10.0, static_cast(order)); - - unsigned int unit = 0; - - do - { - tick_period = order_decimal * ScaleUnits[unit++]; - } while (tick_period < _min_period && unit < countof(ScaleUnits)); - - prefix = ceil((order - FirstSIPrefixPower) / 3.0f); - assert(prefix < countof(SIPrefixes)); - - - typical_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, - AlignLeft | AlignTop, format_time(_view.offset() * _view.scale(), - prefix)).width() + MinValueSpacing; - - min_width += SpacingIncrement; - - } while(typical_width > tick_period / _view.scale()); - - const int text_height = p.boundingRect(0, 0, INT_MAX, INT_MAX, - AlignLeft | AlignTop, "8").height(); - - // Draw the tick marks - p.setPen(dsBlue); - - const double minor_tick_period = tick_period / MinorTickSubdivision; - const double first_major_division = - floor(_view.offset() * _view.scale() / tick_period); - const double first_minor_division = - ceil(_view.offset() * _view.scale() / minor_tick_period); - const double t0 = first_major_division * tick_period; - - int division = (int)round(first_minor_division - - first_major_division * MinorTickSubdivision) - 1; - - const int major_tick_y1 = text_height + ValueMargin * 3; - const int tick_y2 = height(); - const int minor_tick_y1 = (major_tick_y1 + tick_y2) / 2; - - double x; - - do { - const double t = t0 + division * minor_tick_period; - x = t / _view.scale() - _view.offset(); - - if (division % MinorTickSubdivision == 0) - { - // Draw a major tick - p.drawText(x, 2 * ValueMargin, 0, text_height, - AlignCenter | AlignTop | TextDontClip, - format_time(t, prefix)); - p.drawLine(QPointF(x, major_tick_y1), - QPointF(x, tick_y2)); - } - else - { - // Draw a minor tick - p.drawLine(QPointF(x, minor_tick_y1), - QPointF(x, tick_y2)); - } - - division++; - - } while (x < _view.get_view_width()); - - // Draw the cursors - if (!_view.get_cursorList().empty()) { - list::iterator i = _view.get_cursorList().begin(); - int index = 1; - while (i != _view.get_cursorList().end()) { - (*i)->paint_label(p, rect(), prefix, index); - index++; - i++; - } - } -} - void Ruler::draw_logic_tick_mark(QPainter &p) { using namespace Qt; @@ -476,7 +364,9 @@ void Ruler::draw_logic_tick_mark(QPainter &p) AlignLeft | AlignTop, "8").height(); // Draw the tick marks - p.setPen(Trace::DARK_FORE); + QColor fore(QWidget::palette().color(QWidget::foregroundRole())); + fore.setAlpha(View::ForeAlpha); + p.setPen(fore); const double minor_tick_period = tick_period / MinPeriodScale; const int minor_order = (int)floorf(log10f(minor_tick_period)); @@ -564,16 +454,14 @@ void Ruler::draw_hover_mark(QPainter &p) if (x == -1 || _grabbed_marker) return; - p.setPen(QPen(Qt::NoPen)); - p.setBrush(RULER_COLOR); + QColor fore(QWidget::palette().color(QWidget::foregroundRole())); + p.setPen(fore); + p.setBrush(fore); const int b = height() - 1; - const QPointF points[] = { - QPointF(x, b), - QPointF(x - HoverArrowSize, b - HoverArrowSize), - QPointF(x + HoverArrowSize, b - HoverArrowSize) - }; - p.drawPolygon(points, countof(points)); + for (int i = 0; i < HoverArrowSize; i++) + for (int j = -i; j <= i; j++) + p.drawPoint(x-j, b-i); } void Ruler::draw_cursor_sel(QPainter &p) @@ -582,11 +470,11 @@ void Ruler::draw_cursor_sel(QPainter &p) return; p.setPen(QPen(Qt::NoPen)); - p.setBrush(dsBlue); + p.setBrush(View::Blue); const QPoint pos = QPoint(_view.hover_point().x(), _view.hover_point().y()); if (in_cursor_sel_rect(pos) == 0) - p.setBrush(HitColor); + p.setBrush(View::Orange); const int y = height(); const QRectF selRect = get_cursor_sel_rect(0); @@ -616,7 +504,7 @@ void Ruler::draw_cursor_sel(QPainter &p) cursorRect.left(), cursorRect.bottom() - 3); p.setPen(QPen(Qt::NoPen)); if (in_cursor_sel_rect(pos) == index) - p.setBrush(HitColor); + p.setBrush(View::Orange); else p.setBrush(CursorColor[(index - 1)%8]); p.drawRect(cursorRect); diff --git a/DSView/pv/view/ruler.h b/DSView/pv/view/ruler.h old mode 100644 new mode 100755 index d9df2ed4361fa3c9876f5260e104a9df9a638925..63dff2318b600bbfb8ce0f4be1e98d97237d1e5f --- a/DSView/pv/view/ruler.h +++ b/DSView/pv/view/ruler.h @@ -50,16 +50,8 @@ private: static const int HoverArrowSize; static const int CursorSelWidth; - static const QColor dsBlue; - static const QColor dsYellow; - static const QColor dsRed; - static const QColor dsGreen; - static const QColor RULER_COLOR; - public: static const QColor CursorColor[8]; - static const QColor HitColor; - static const QColor WarnColor; public: Ruler(View &parent); @@ -86,7 +78,6 @@ private: void leaveEvent(QEvent *); private: - void draw_tick_mark(QPainter &p); void draw_logic_tick_mark(QPainter &p); /** * Draw a hover arrow under the cursor position. diff --git a/DSView/pv/view/selectableitem.cpp b/DSView/pv/view/selectableitem.cpp old mode 100644 new mode 100755 diff --git a/DSView/pv/view/selectableitem.h b/DSView/pv/view/selectableitem.h old mode 100644 new mode 100755 diff --git a/DSView/pv/view/signal.cpp b/DSView/pv/view/signal.cpp old mode 100644 new mode 100755 index 54880748aa4cb076539fd49587c3dfaab2cac40b..84efd3be2013f99958e78b28131fc4bd6b3bf8c6 --- a/DSView/pv/view/signal.cpp +++ b/DSView/pv/view/signal.cpp @@ -60,12 +60,6 @@ void Signal::set_name(QString name) _probe->name = g_strdup(name.toLocal8Bit().data()); } -void Signal::paint_axis(QPainter &p, int y, int left, int right) -{ - p.setPen(SignalAxisPen); - p.drawLine(QPointF(left, y + 0.5f), QPointF(right, y + 0.5f)); -} - boost::shared_ptr Signal::get_device() const { return _dev_inst; diff --git a/DSView/pv/view/signal.h b/DSView/pv/view/signal.h old mode 100644 new mode 100755 index 944fa7c9ebda949fe9503d0eb3057cc2a243366d..0c37ca9d0cce2202e0966e7aa128b1f7add40520 --- a/DSView/pv/view/signal.h +++ b/DSView/pv/view/signal.h @@ -52,6 +52,8 @@ namespace view { class Signal : public Trace { + Q_OBJECT + private: @@ -89,17 +91,6 @@ public: boost::shared_ptr get_device() const; -protected: - - /** - * Paints a zero axis across the viewport. - * @param p the QPainter to paint into. - * @param y the y-offset of the axis. - * @param left the x-coordinate of the left edge of the view. - * @param right the x-coordinate of the right edge of the view. - */ - void paint_axis(QPainter &p, int y, int left, int right); - protected: boost::shared_ptr _dev_inst; sr_channel *const _probe; diff --git a/DSView/pv/view/spectrumtrace.cpp b/DSView/pv/view/spectrumtrace.cpp new file mode 100755 index 0000000000000000000000000000000000000000..8b461ee5f9be4cc72080dc3dccd0039631e46934 --- /dev/null +++ b/DSView/pv/view/spectrumtrace.cpp @@ -0,0 +1,494 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2016 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include +#include + +#include "spectrumtrace.h" +#include "../sigsession.h" +#include "../data/dso.h" +#include "../data/dsosnapshot.h" +#include "../view/dsosignal.h" +#include "../view/viewport.h" +#include "../device/devinst.h" +#include "../data/spectrumstack.h" + +using namespace boost; +using namespace std; + +namespace pv { +namespace view { + +const int SpectrumTrace::UpMargin = 0; +const int SpectrumTrace::DownMargin = 0; +const int SpectrumTrace::RightMargin = 30; +const QString SpectrumTrace::FFT_ViewMode[2] = { + "Linear RMS", + "DBV RMS" +}; + +const QString SpectrumTrace::FreqPrefixes[9] = + {"", "", "", "", "K", "M", "G", "T", "P"}; +const int SpectrumTrace::FirstSIPrefixPower = -9; +const int SpectrumTrace::LastSIPrefixPower = 15; +const int SpectrumTrace::Pricision = 2; +const int SpectrumTrace::FreqMinorDivNum = 10; +const int SpectrumTrace::TickHeight = 15; +const int SpectrumTrace::VolDivNum = 5; + +const int SpectrumTrace::DbvRanges[4] = { + 100, + 120, + 150, + 200, +}; + +const int SpectrumTrace::HoverPointSize = 3; +const double SpectrumTrace::VerticalRate = 1.0 / 2000.0; + +SpectrumTrace::SpectrumTrace(pv::SigSession &session, + boost::shared_ptr spectrum_stack, int index) : + Trace("FFT("+QString::number(index)+")", index, SR_CHANNEL_FFT), + _session(session), + _spectrum_stack(spectrum_stack), + _enable(false), + _view_mode(0), + _hover_en(false), + _scale(1), + _offset(0) +{ + _typeWidth = 0; + const vector< boost::shared_ptr > sigs(_session.get_signals()); + for(size_t i = 0; i < sigs.size(); i++) { + const boost::shared_ptr s(sigs[i]); + assert(s); + if (dynamic_pointer_cast(s) && index == s->get_index()) + _colour = s->get_colour(); + } +} + +SpectrumTrace::~SpectrumTrace() +{ + +} + +bool SpectrumTrace::enabled() const +{ + return _enable; +} + +void SpectrumTrace::set_enable(bool enable) +{ + _enable = enable; +} + +int SpectrumTrace::view_mode() const +{ + return _view_mode; +} + +void SpectrumTrace::set_view_mode(unsigned int mode) +{ + assert(mode < sizeof(FFT_ViewMode)/sizeof(FFT_ViewMode[0])); + _view_mode = mode; +} + +std::vector SpectrumTrace::get_view_modes_support() +{ + std::vector modes; + for (unsigned int i = 0; i < sizeof(FFT_ViewMode)/sizeof(FFT_ViewMode[0]); i++) { + modes.push_back(FFT_ViewMode[i]); + } + return modes; +} + +const boost::shared_ptr& SpectrumTrace::get_spectrum_stack() const +{ + return _spectrum_stack; +} + +void SpectrumTrace::init_zoom() +{ + _scale = 1; + _offset = 0; +} + +void SpectrumTrace::zoom(double steps, int offset) +{ + if (!_view) + return; + + const int width = get_view_rect().width(); + double pre_offset = _offset + _scale*offset/width; + _scale *= std::pow(3.0/2.0, -steps); + _scale = max(min(_scale, 1.0), 100.0/_spectrum_stack->get_sample_num()); + _offset = pre_offset - _scale*offset/width; + _offset = max(min(_offset, 1-_scale), 0.0); + + _view->set_update(_viewport, true); + _view->update(); +} + +void SpectrumTrace::set_offset(double delta) +{ + int width = get_view_rect().width(); + _offset = _offset + (delta*_scale / width); + _offset = max(min(_offset, 1-_scale), 0.0); + + _view->set_update(_viewport, true); + _view->update(); +} + +double SpectrumTrace::get_offset() const +{ + return _offset; +} + +void SpectrumTrace::set_scale(double scale) +{ + _scale = max(min(scale, 1.0), 100.0/_spectrum_stack->get_sample_num()); + + _view->set_update(_viewport, true); + _view->update(); +} + +double SpectrumTrace::get_scale() const +{ + return _scale; +} + +void SpectrumTrace::set_dbv_range(int range) +{ + _dbv_range = range; +} + +int SpectrumTrace::dbv_range() const +{ + return _dbv_range; +} + +std::vector SpectrumTrace::get_dbv_ranges() +{ + std::vector range; + for (unsigned int i = 0; i < sizeof(DbvRanges)/sizeof(DbvRanges[0]); i++) { + range.push_back(DbvRanges[i]); + } + return range; +} + +QString SpectrumTrace::format_freq(double freq, unsigned precision) +{ + if (freq <= 0) { + return "0Hz"; + } else { + const int order = floor(log10f(freq)); + assert(order >= FirstSIPrefixPower); + assert(order <= LastSIPrefixPower); + const int prefix = floor((order - FirstSIPrefixPower)/ 3.0f); + const double divider = pow(10.0, max(prefix * 3.0 + FirstSIPrefixPower, 0.0)); + + QString s; + QTextStream ts(&s); + ts.setRealNumberPrecision(precision); + ts << fixed << freq / divider << + FreqPrefixes[prefix] << "Hz"; + return s; + } +} + +bool SpectrumTrace::measure(const QPoint &p) +{ + _hover_en = false; + if(!_view || !enabled()) + return false; + + const QRect window = get_view_rect(); + if (!window.contains(p)) + return false; + + const std::vector samples(_spectrum_stack->get_fft_spectrum()); + if(samples.empty()) + return false; + + const unsigned int full_size = (_spectrum_stack->get_sample_num()/2); + const double view_off = full_size * _offset; + const double view_size = full_size*_scale; + const double sample_per_pixels = view_size/window.width(); + _hover_index = std::round(p.x() * sample_per_pixels + view_off); + + if (_hover_index < full_size) + _hover_en = true; + + //_view->set_update(_viewport, true); + _view->update(); + return true; +} + + +void SpectrumTrace::paint_back(QPainter &p, int left, int right, QColor fore, QColor back) +{ + if(!_view) + return; + + const int height = get_view_rect().height(); + const int width = right - left; + + fore.setAlpha(View::BackAlpha); + QPen solidPen(fore); + solidPen.setStyle(Qt::SolidLine); + p.setPen(solidPen); + p.setBrush(back.black() > 0x80 ? back.darker() : back.lighter()); + p.drawRect(left, UpMargin, width, height); +} + +void SpectrumTrace::paint_mid(QPainter &p, int left, int right, QColor fore, QColor back) +{ + (void)fore; + (void)back; + + if(!_view) + return; + assert(right >= left); + + if (enabled()) { + const std::vector samples(_spectrum_stack->get_fft_spectrum()); + if(samples.empty()) + return; + + QColor trace_colour = _colour; + trace_colour.setAlpha(View::ForeAlpha); + p.setPen(trace_colour); + + const int full_size = (_spectrum_stack->get_sample_num()/2); + const double view_off = full_size * _offset; + const int view_start = floor(view_off); + const int view_size = full_size*_scale; + QPointF *points = new QPointF[samples.size()]; + QPointF *point = points; + + const bool dc_ignored = _spectrum_stack->dc_ignored(); + const double height = get_view_rect().height(); + const double width = right - left; + const double pixels_per_sample = width/view_size; + + double vdiv = 0; + double vfactor = 0; + BOOST_FOREACH(const boost::shared_ptr s, _session.get_signals()) { + boost::shared_ptr dsoSig; + if ((dsoSig = dynamic_pointer_cast(s))) { + if(dsoSig->get_index() == _spectrum_stack->get_index()) { + vdiv = dsoSig->get_vDialValue(); + vfactor = dsoSig->get_factor(); + break; + } + } + } + if (_view_mode == 0) { + _vmin = 0; + _vmax = (vdiv*DS_CONF_DSO_HDIVS*vfactor)*VerticalRate; + } else { + _vmax = 20*log10((vdiv*DS_CONF_DSO_HDIVS*vfactor)*VerticalRate); + _vmin = _vmax - _dbv_range; + } + + //const double max_value = *std::max_element(dc_ignored ? ++samples.begin() : samples.begin(), samples.end()); + //const double min_value = *std::min_element(dc_ignored ? ++samples.begin() : samples.begin(), samples.end()); + //_vmax = (_view_mode == 0) ? max_value : 20*log10(max_value); + //_vmin = (_view_mode == 0) ? min_value : 20*log10(min_value); + const double scale = height / (_vmax - _vmin); + + double x = (view_start-view_off)*pixels_per_sample; + uint64_t sample = view_start; + if (dc_ignored && sample == 0) { + sample++; + x += pixels_per_sample; + } + double min_mag = pow(10.0, _vmin/20); + do{ + double mag = samples[sample]; + if (_view_mode != 0) { + if (mag < min_mag) + mag = _vmin; + else + mag = 20*log10(mag); + } + const double y = height - (scale * (mag - _vmin)); + *point++ = QPointF(x, y); + x += pixels_per_sample; + sample++; + }while(x= left); + + (void)left; + (void)right; + const int text_height = p.boundingRect(0, 0, INT_MAX, INT_MAX, + AlignLeft | AlignTop, "8").height(); + const double width = get_view_rect().width(); + const double height = get_view_rect().height(); + double blank_top = 0; + double blank_right = width; + + // horizontal ruler + const double NyFreq = _session.cur_samplerate() / (2.0 * _spectrum_stack->get_sample_interval()); + const double deltaFreq = _session.cur_samplerate() * 1.0 / + (_spectrum_stack->get_sample_num() * _spectrum_stack->get_sample_interval()); + const double FreqRange = NyFreq * _scale; + const double FreqOffset = NyFreq * _offset; + + const int order = (int)floor(log10(FreqRange)); + const double multiplier = (pow(10.0, order) == FreqRange) ? FreqRange/10 : pow(10.0, order); + const double freq_per_pixel = FreqRange / width; + + p.setPen(fore); + p.setBrush(Qt::NoBrush); + double tick_freq = multiplier * (int)floor(FreqOffset / multiplier); + int division = (int)round(tick_freq * FreqMinorDivNum / multiplier); + double x = (tick_freq - FreqOffset) / freq_per_pixel; + do{ + if (division%FreqMinorDivNum == 0) { + QString freq_str = format_freq(tick_freq); + double typical_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, + AlignLeft | AlignTop, freq_str).width() + 10; + p.drawLine(x, 1, x, TickHeight); + if (x > typical_width/2 && (width-x) > typical_width/2) + p.drawText(x-typical_width/2, TickHeight, typical_width, text_height, + AlignCenter | AlignTop | TextDontClip, freq_str); + } else { + p.drawLine(x, 1, x, TickHeight/2); + } + tick_freq += multiplier/FreqMinorDivNum; + division++; + x = (tick_freq - FreqOffset) / freq_per_pixel; + } while(x < width); + blank_top = max(blank_top, (double)TickHeight + text_height); + + // delta Frequency + QString freq_str = QString::fromWCharArray(L" \u0394") + "Freq: " + format_freq(deltaFreq,4); + p.drawText(0, 0, width, get_view_rect().height(), + AlignRight | AlignBottom | TextDontClip, freq_str); + double delta_left = width-p.boundingRect(0, 0, INT_MAX, INT_MAX, + AlignLeft | AlignTop, freq_str).width(); + blank_right = min(delta_left, blank_right); + + // Vertical ruler + const double vRange = _vmax - _vmin; + const double vOffset = _vmin; + const double vol_per_tick = vRange / VolDivNum; + + p.setPen(fore); + p.setBrush(Qt::NoBrush); + double tick_vol = vol_per_tick + vOffset; + double y = height - height / VolDivNum; + const QString unit = (_view_mode == 0) ? "" : "dbv"; + do{ + if (y > text_height && y < (height - text_height)) { + QString vol_str = QString::number(tick_vol, 'f', Pricision) + unit; + double vol_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, + AlignLeft | AlignTop, vol_str).width(); + p.drawLine(width, y, width-TickHeight/2, y); + p.drawText(width-TickHeight-vol_width, y-text_height/2, vol_width, text_height, + AlignCenter | AlignTop | TextDontClip, vol_str); + blank_right = min(width-TickHeight-vol_width, blank_right); + } + tick_vol += vol_per_tick; + y -= height / VolDivNum; + } while(y > 0); + + // Hover measure + if (_hover_en) { + const std::vector samples(_spectrum_stack->get_fft_spectrum()); + if(samples.empty()) + return; + const int full_size = (_spectrum_stack->get_sample_num()/2); + const double view_off = full_size * _offset; + const int view_size = full_size*_scale; + const double scale = height / (_vmax - _vmin); + const double pixels_per_sample = width/view_size; + double x = (_hover_index-view_off)*pixels_per_sample; + double min_mag = pow(10.0, _vmin/20); + _hover_value = samples[_hover_index]; + if (_view_mode != 0) { + if (_hover_value < min_mag) + _hover_value = _vmin; + else + _hover_value = 20*log10(_hover_value); + } + const double y = height - (scale * (_hover_value - _vmin)); + _hover_point = QPointF(x, y); + + p.setPen(QPen(fore, 1, Qt::DashLine)); + p.setBrush(Qt::NoBrush); + p.drawLine(_hover_point.x(), 0, _hover_point.x(), height); + + QString hover_str = QString::number(_hover_value, 'f', 4) + unit + "@" + format_freq(deltaFreq * _hover_index, 4); + const int hover_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, + AlignLeft | AlignTop, hover_str).width(); + const int hover_height = p.boundingRect(0, 0, INT_MAX, INT_MAX, + AlignLeft | AlignTop, hover_str).height(); + QRectF hover_rect(_hover_point.x(), _hover_point.y()-hover_height, hover_width, hover_height); + if (hover_rect.right() > blank_right) + hover_rect.moveRight(min(_hover_point.x(), blank_right)); + if (hover_rect.top() < blank_top) + hover_rect.moveTop(max(_hover_point.y(), blank_top)); + if (hover_rect.top() > 0) + p.drawText(hover_rect, AlignCenter | AlignTop | TextDontClip, hover_str); + + p.setPen(Qt::NoPen); + p.setBrush(fore); + p.drawEllipse(_hover_point, HoverPointSize, HoverPointSize); + } +} + +void SpectrumTrace::paint_type_options(QPainter &p, int right, const QPoint pt, QColor fore) +{ + (void)p; + (void)pt; + (void)right; + (void)fore; +} + +QRect SpectrumTrace::get_view_rect() const +{ + assert(_viewport); + return QRect(0, UpMargin, + _viewport->width() - RightMargin, + _viewport->height() - UpMargin - DownMargin); +} + +} // namespace view +} // namespace pv diff --git a/DSView/pv/view/spectrumtrace.h b/DSView/pv/view/spectrumtrace.h new file mode 100755 index 0000000000000000000000000000000000000000..e8a08796a07a810cab009209905f63f066e73a05 --- /dev/null +++ b/DSView/pv/view/spectrumtrace.h @@ -0,0 +1,156 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2016 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef DSVIEW_PV_VIEW_SPECTRUMTRACE_H +#define DSVIEW_PV_VIEW_SPECTRUMTRACE_H + +#include "trace.h" + +#include +#include + +#include + +struct srd_channel; + +namespace pv { + +class SigSession; + +namespace data{ +class SpectrumStack; +} + +namespace view { + +class SpectrumTrace : public Trace +{ + Q_OBJECT + +private: + static const int UpMargin; + static const int DownMargin; + static const int RightMargin; + static const QString FFT_ViewMode[2]; + + static const QString FreqPrefixes[9]; + static const int FirstSIPrefixPower; + static const int LastSIPrefixPower; + static const int Pricision; + static const int FreqMinorDivNum; + static const int TickHeight; + static const int VolDivNum; + + static const int DbvRanges[4]; + + static const int HoverPointSize; + + static const double VerticalRate; + +public: + SpectrumTrace(pv::SigSession &session, + boost::shared_ptr spectrum_stack, int index); + ~SpectrumTrace(); + + bool enabled() const; + void set_enable(bool enable); + + void init_zoom(); + void zoom(double steps, int offset); + bool zoom_hit() const; + void set_zoom_hit(bool hit); + + void set_offset(double delta); + double get_offset() const; + + void set_scale(double scale); + double get_scale() const; + + void set_dbv_range(int range); + int dbv_range() const; + std::vector get_dbv_ranges(); + + int view_mode() const; + void set_view_mode(unsigned int mode); + std::vector get_view_modes_support(); + + const boost::shared_ptr& get_spectrum_stack() const; + + static QString format_freq(double freq, unsigned precision = Pricision); + + bool measure(const QPoint &p); + + /** + * Paints the background layer of the trace with a QPainter + * @param p the QPainter to paint into. + * @param left the x-coordinate of the left edge of the signal. + * @param right the x-coordinate of the right edge of the signal. + **/ + void paint_back(QPainter &p, int left, int right, QColor fore, QColor back); + + /** + * Paints the mid-layer of the trace with a QPainter + * @param p the QPainter to paint into. + * @param left the x-coordinate of the left edge of the signal + * @param right the x-coordinate of the right edge of the signal + **/ + void paint_mid(QPainter &p, int left, int right, QColor fore, QColor back); + + /** + * Paints the foreground layer of the trace with a QPainter + * @param p the QPainter to paint into. + * @param left the x-coordinate of the left edge of the signal + * @param right the x-coordinate of the right edge of the signal + **/ + void paint_fore(QPainter &p, int left, int right, QColor fore, QColor back); + + QRect get_view_rect() const; + +protected: + void paint_type_options(QPainter &p, int right, const QPoint pt, QColor fore); + +private: + +private slots: + +private: + pv::SigSession &_session; + boost::shared_ptr _spectrum_stack; + + bool _enable; + int _view_mode; + + double _vmax; + double _vmin; + int _dbv_range; + + uint64_t _hover_index; + bool _hover_en; + QPointF _hover_point; + double _hover_value; + + double _scale; + double _offset; +}; + +} // namespace view +} // namespace pv + +#endif // DSVIEW_PV_VIEW_SPECTRUMTRACE_H diff --git a/DSView/pv/view/timemarker.cpp b/DSView/pv/view/timemarker.cpp old mode 100644 new mode 100755 index c907991f7c97c893a872f15811fb4ad9eae61266..31eb74428522ddaedc4497369bf4981de004be16 --- a/DSView/pv/view/timemarker.cpp +++ b/DSView/pv/view/timemarker.cpp @@ -84,9 +84,12 @@ void TimeMarker::paint(QPainter &p, const QRect &rect, const bool highlight, int const double scale = _view.scale(); const double samples_per_pixel = sample_rate * scale; const int64_t x = _index/samples_per_pixel - _view.offset(); - QColor color = (order == -1) ? _colour : Ruler::CursorColor[order%8]; - p.setPen((_grabbed | highlight) ? QPen(color.lighter(), 2, Qt::DashLine) : QPen(color, 1, Qt::DashLine)); - p.drawLine(QPoint(x, rect.top()), QPoint(x, rect.bottom())); + if (x <= rect.right()) { + QColor color = (order == -1) ? _colour : Ruler::CursorColor[order%8]; + p.setPen((_grabbed | highlight) ? QPen(color.lighter(), 2, Qt::DashLine) : QPen(color, 1, Qt::DashLine)); + //p.drawLine(QPoint(x, rect.top()), QPoint(x, rect.bottom())); + p.drawLine(QPoint(x, 0), QPoint(x, rect.bottom())); + } } } // namespace view diff --git a/DSView/pv/view/timemarker.h b/DSView/pv/view/timemarker.h old mode 100644 new mode 100755 diff --git a/DSView/pv/view/trace.cpp b/DSView/pv/view/trace.cpp old mode 100644 new mode 100755 index 7ca99fda1380348c2c80dce5e123b885bda1e629..f48c0d5381872695c389fd36654bc27b64ce957b --- a/DSView/pv/view/trace.cpp +++ b/DSView/pv/view/trace.cpp @@ -36,24 +36,6 @@ namespace pv { namespace view { -const QColor Trace::dsBlue = QColor(17, 133, 209, 255); -const QColor Trace::dsYellow = QColor(238, 178, 17, 255); -const QColor Trace::dsRed = QColor(213, 15, 37, 255); -const QColor Trace::dsGreen = QColor(0, 153, 37, 200); -const QColor Trace::dsGray = QColor(0x88, 0x8A, 0x85, 60); -const QColor Trace::dsFore = QColor(0xff, 0xff, 0xff, 60); -const QColor Trace::dsBack = QColor(0x16, 0x18, 0x23, 200); -const QColor Trace::dsDisable = QColor(0x88, 0x8A, 0x85, 200); -const QColor Trace::dsActive = QColor(17, 133, 209, 255); -const QColor Trace::dsLightBlue = QColor(17, 133, 209, 150); -const QColor Trace::dsLightRed = QColor(213, 15, 37, 150); -const QPen Trace::SignalAxisPen = QColor(128, 128, 128, 64); - -const QColor Trace::DARK_BACK = QColor(48, 47, 47, 255); -const QColor Trace::DARK_FORE = QColor(150, 150, 150, 255); -const QColor Trace::DARK_HIGHLIGHT = QColor(32, 32, 32, 255); -const QColor Trace::DARK_BLUE = QColor(17, 133, 209, 255); - const QColor Trace::PROBE_COLORS[8] = { QColor(0x50, 0x50, 0x50), // Black QColor(0x8F, 0x52, 0x02), // Brown @@ -63,17 +45,7 @@ const QColor Trace::PROBE_COLORS[8] = { QColor(0x73, 0xD2, 0x16), // Green QColor(0x34, 0x65, 0xA4), // Blue QColor(0x75, 0x50, 0x7B), // Violet -// QColor(17, 133, 209), -// QColor(17, 133, 209), -// QColor(17, 133, 209), -// QColor(17, 133, 209), -// QColor(17, 133, 209), -// QColor(17, 133, 209), -// QColor(17, 133, 209), -// QColor(17, 133, 209), }; - -const QPen Trace::AxisPen(QColor(128, 128, 128, 64)); const int Trace::LabelHitPadding = 2; Trace::Trace(QString name, uint16_t index, int type) : @@ -239,30 +211,37 @@ pv::view::Viewport* Trace::get_viewport() const return _viewport; } -void Trace::paint_back(QPainter &p, int left, int right) +void Trace::paint_back(QPainter &p, int left, int right, QColor fore, QColor back) { - QPen pen(Signal::dsGray); + (void)back; + + fore.setAlpha(View::BackAlpha); + QPen pen(fore); pen.setStyle(Qt::DotLine); p.setPen(pen); const double sigY = get_y(); p.drawLine(left, sigY, right, sigY); } -void Trace::paint_mid(QPainter &p, int left, int right) +void Trace::paint_mid(QPainter &p, int left, int right, QColor fore, QColor back) { (void)p; (void)left; (void)right; + (void)fore; + (void)back; } -void Trace::paint_fore(QPainter &p, int left, int right) +void Trace::paint_fore(QPainter &p, int left, int right, QColor fore, QColor back) { (void)p; (void)left; (void)right; + (void)fore; + (void)back; } -void Trace::paint_label(QPainter &p, int right, const QPoint pt) +void Trace::paint_label(QPainter &p, int right, const QPoint pt, QColor fore) { if (_type == SR_CHANNEL_FFT && !enabled()) return; @@ -274,24 +253,26 @@ void Trace::paint_label(QPainter &p, int right, const QPoint pt) const QRectF name_rect = get_rect("name", y, right); const QRectF label_rect = get_rect("label", get_zero_vpos(), right); - //p.setRenderHint(QPainter::Antialiasing); // Paint the ColorButton + QColor foreBack = fore; + foreBack.setAlpha(View::BackAlpha); p.setPen(Qt::transparent); - p.setBrush(enabled() ? _colour : dsDisable); + p.setBrush(enabled() ? (_colour.isValid() ? _colour : fore) : foreBack); p.drawRect(color_rect); - if (_type == SR_CHANNEL_DSO) { - p.setPen(enabled() ? Qt::white: dsDisable); + if (_type == SR_CHANNEL_DSO || + _type == SR_CHANNEL_MATH) { + p.setPen(enabled() ? Qt::white: foreBack); p.drawText(color_rect, Qt::AlignCenter | Qt::AlignVCenter, _name); } if (_type != SR_CHANNEL_DSO) { // Paint the signal name - p.setPen(enabled() ? DARK_FORE: dsDisable); + p.setPen(enabled() ? fore: foreBack); p.drawText(name_rect, Qt::AlignLeft | Qt::AlignVCenter, _name); } // Paint the trigButton - paint_type_options(p, right, pt); + paint_type_options(p, right, pt, fore); // Paint the label if (enabled()) { @@ -306,7 +287,8 @@ void Trace::paint_label(QPainter &p, int right, const QPoint pt) p.setPen(Qt::transparent); if (_type == SR_CHANNEL_DSO || _type == SR_CHANNEL_FFT || - _type == SR_CHANNEL_ANALOG) { + _type == SR_CHANNEL_ANALOG || + _type == SR_CHANNEL_MATH) { p.setBrush(_colour); p.drawPolygon(points, countof(points)); } else { @@ -349,17 +331,20 @@ void Trace::paint_label(QPainter &p, int right, const QPoint pt) else if (_type == SR_CHANNEL_DECODER) p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "D"); else if (_type == SR_CHANNEL_FFT) + p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "F"); + else if (_type == SR_CHANNEL_MATH) p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "M"); else p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, QString::number(_index_list.front())); } } -void Trace::paint_type_options(QPainter &p, int right, const QPoint pt) +void Trace::paint_type_options(QPainter &p, int right, const QPoint pt, QColor fore) { (void)p; (void)right; (void)pt; + (void)fore; } bool Trace::mouse_double_click(int right, const QPoint pt) @@ -400,12 +385,6 @@ int Trace::pt_in_rect(int y, int right, const QPoint &point) return 0; } -void Trace::paint_axis(QPainter &p, int y, int left, int right) -{ - p.setPen(SignalAxisPen); - p.drawLine(QPointF(left, y + 0.5f), QPointF(right, y + 0.5f)); -} - void Trace::compute_text_size(QPainter &p) { _text_size = QSize( diff --git a/DSView/pv/view/trace.h b/DSView/pv/view/trace.h old mode 100644 new mode 100755 index b0a92496eb3f687f917e8014d3f026e249d14154..30880f03213a195fd8670769da3c2230977ae7a6 --- a/DSView/pv/view/trace.h +++ b/DSView/pv/view/trace.h @@ -49,7 +49,6 @@ class Trace : public SelectableItem protected: static const int Margin = 3; static const int SquareNum = 5; - static const QPen AxisPen; static const int LabelHitPadding; public: @@ -58,24 +57,6 @@ public: static const int NAME = 2; static const int LABEL = 8; - static const QColor dsBlue; - static const QColor dsYellow; - static const QColor dsRed; - static const QColor dsGreen; - static const QColor dsGray; - static const QColor dsFore; - static const QColor dsBack; - static const QColor dsDisable; - static const QColor dsActive; - static const QColor dsLightBlue; - static const QColor dsLightRed; - static const QPen SignalAxisPen; - - static const QColor DARK_BACK; - static const QColor DARK_FORE; - static const QColor DARK_HIGHLIGHT; - static const QColor DARK_BLUE; - static const QColor PROBE_COLORS[8]; protected: @@ -178,7 +159,7 @@ public: * @param left the x-coordinate of the left edge of the signal * @param right the x-coordinate of the right edge of the signal **/ - virtual void paint_back(QPainter &p, int left, int right); + virtual void paint_back(QPainter &p, int left, int right, QColor fore, QColor back); /** * Paints the mid-layer of the trace with a QPainter @@ -186,7 +167,7 @@ public: * @param left the x-coordinate of the left edge of the signal * @param right the x-coordinate of the right edge of the signal **/ - virtual void paint_mid(QPainter &p, int left, int right); + virtual void paint_mid(QPainter &p, int left, int right, QColor fore, QColor back); /** * Paints the foreground layer of the trace with a QPainter @@ -194,7 +175,7 @@ public: * @param left the x-coordinate of the left edge of the signal * @param right the x-coordinate of the right edge of the signal **/ - virtual void paint_fore(QPainter &p, int left, int right); + virtual void paint_fore(QPainter &p, int left, int right, QColor fore, QColor back); /** * Paints the trace label. @@ -203,7 +184,7 @@ public: * area. * @param point the mouse point. */ - virtual void paint_label(QPainter &p, int right, const QPoint pt); + virtual void paint_label(QPainter &p, int right, const QPoint pt, QColor fore); /** * Gets the y-offset of the axis. @@ -258,15 +239,6 @@ protected: */ QColor get_text_colour() const; - /** - * Paints a zero axis across the viewport. - * @param p the QPainter to paint into. - * @param y the y-offset of the axis. - * @param left the x-coordinate of the left edge of the view. - * @param right the x-coordinate of the right edge of the view. - */ - void paint_axis(QPainter &p, int y, int left, int right); - /** * Paints optoins for different trace type. * @param p the QPainter to paint into. @@ -274,7 +246,7 @@ protected: * area. * @param point the mouse point. */ - virtual void paint_type_options(QPainter &p, int right, const QPoint pt); + virtual void paint_type_options(QPainter &p, int right, const QPoint pt, QColor fore); private: diff --git a/DSView/pv/view/view.cpp b/DSView/pv/view/view.cpp old mode 100644 new mode 100755 index e57474a0d8e29aa7ee64e2bf90d315ef59fa9e6d..8c2823c2c0dbd3e65b829cca9eed87511bba5c76 --- a/DSView/pv/view/view.cpp +++ b/DSView/pv/view/view.cpp @@ -40,13 +40,16 @@ #include "dsosignal.h" #include "view.h" #include "viewport.h" -#include "mathtrace.h" +#include "spectrumtrace.h" +#include "lissajoustrace.h" +#include "analogsignal.h" #include "../device/devinst.h" #include "pv/sigsession.h" #include "pv/data/logic.h" #include "pv/data/logicsnapshot.h" #include "pv/dialogs/calibration.h" +#include "pv/dialogs/lissajousoptions.h" using namespace boost; using namespace std; @@ -61,13 +64,21 @@ const int View::MaxScrollValue = INT_MAX / 2; const int View::MaxHeightUnit = 20; //const int View::SignalHeight = 30;s -const int View::SignalMargin = 10; +const int View::SignalMargin = 7; const int View::SignalSnapGridSize = 10; const QColor View::CursorAreaColour(220, 231, 243); const QSizeF View::LabelPadding(4, 4); +const QColor View::Red = QColor(213, 15, 37, 255); +const QColor View::Orange = QColor(238, 178, 17, 255); +const QColor View::Blue = QColor(17, 133, 209, 255); +const QColor View::Green = QColor(0, 153, 37, 255); +const QColor View::Purple = QColor(109, 50, 156, 255); +const QColor View::LightBlue = QColor(17, 133, 209, 200); + + View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget *parent) : QScrollArea(parent), _session(session), @@ -81,8 +92,11 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget _updating_scroll(false), _show_cursors(false), _search_hit(false), + _show_xcursors(false), _hover_point(-1, -1), - _dso_auto(true) + _dso_auto(true), + _show_lissajous(false), + _back_ready(false) { setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); @@ -98,6 +112,8 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget _trace_view_map[SR_CHANNEL_ANALOG] = TIME_VIEW; _trace_view_map[SR_CHANNEL_DSO] = TIME_VIEW; _trace_view_map[SR_CHANNEL_FFT] = FFT_VIEW; + _trace_view_map[SR_CHANNEL_LISSAJOUS] = TIME_VIEW; + _trace_view_map[SR_CHANNEL_MATH] = TIME_VIEW; _active_viewport = NULL; _ruler = new Ruler(*this); @@ -141,7 +157,7 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget layout->setContentsMargins(0,0,0,0); _viewcenter->setLayout(layout); layout->addWidget(_vsplitter, 0, 0); - _viewbottom = new widgets::ViewStatus(_session, this); + _viewbottom = new ViewStatus(_session, *this); _viewbottom->setFixedHeight(StatusHeight); layout->addWidget(_viewbottom, 1, 0); setViewport(_viewcenter); @@ -167,8 +183,8 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget connect(&_session, SIGNAL(repeat_hold(int)), this, SLOT(repeat_show())); - connect(_devmode, SIGNAL(mode_changed()), - this, SLOT(mode_changed()), Qt::DirectConnection); + connect(_devmode, SIGNAL(dev_changed(bool)), + this, SLOT(dev_changed(bool)), Qt::DirectConnection); connect(_header, SIGNAL(traces_moved()), this, SLOT(on_traces_moved())); @@ -185,11 +201,14 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget _ruler->setObjectName(tr("ViewArea_ruler")); _header->setObjectName(tr("ViewArea_header")); + QColor fore(QWidget::palette().color(QWidget::foregroundRole())); + fore.setAlpha(View::BackAlpha); + _show_trig_cursor = false; - _trig_cursor = new Cursor(*this, Trace::dsLightRed, 0); + _trig_cursor = new Cursor(*this, View::Red, 0); _show_search_cursor = false; _search_pos = 0; - _search_cursor = new Cursor(*this, Trace::dsGray, _search_pos); + _search_cursor = new Cursor(*this, fore, _search_pos); _cali = new pv::dialogs::Calibration(this); _cali->hide(); @@ -231,6 +250,7 @@ void View::capture_init() if (_session.get_device()->dev_inst()->mode == ANALOG) set_scale_offset(_maxscale, 0); status_clear(); + _trig_time_setted = false; } void View::zoom(double steps) @@ -245,8 +265,8 @@ void View::set_update(Viewport *viewport, bool need_update) void View::set_all_update(bool need_update) { - BOOST_FOREACH(Viewport *viewport, _viewport_list) - viewport->set_need_update(need_update); + _time_viewport->set_need_update(need_update); + _fft_viewport->set_need_update(need_update); } double View::get_hori_res() @@ -346,7 +366,7 @@ vector< boost::shared_ptr > View::get_traces(int type) const vector< boost::shared_ptr > decode_sigs( _session.get_decode_signals()); #endif - const vector< boost::shared_ptr > maths(_session.get_math_signals()); + const vector< boost::shared_ptr > spectrums(_session.get_spectrum_traces()); vector< boost::shared_ptr > traces; BOOST_FOREACH(boost::shared_ptr t, sigs) { @@ -364,11 +384,21 @@ vector< boost::shared_ptr > View::get_traces(int type) traces.push_back(t); } - BOOST_FOREACH(boost::shared_ptr t, maths) { + BOOST_FOREACH(boost::shared_ptr t, spectrums) { if (type == ALL_VIEW || _trace_view_map[t->get_type()] == type) traces.push_back(t); } + boost::shared_ptr lissajous = _session.get_lissajous_trace(); + if (lissajous && lissajous->enabled() && + (type == ALL_VIEW || _trace_view_map[lissajous->get_type()] == type)) + traces.push_back(lissajous); + + boost::shared_ptr math = _session.get_math_trace(); + if (math && math->enabled() && + (type == ALL_VIEW || _trace_view_map[math->get_type()] == type)) + traces.push_back(math); + stable_sort(traces.begin(), traces.end(), compare_trace_v_offsets); return traces; } @@ -379,7 +409,9 @@ bool View::compare_trace_v_offsets(const boost::shared_ptr &a, assert(a); assert(b); if (a->get_type() != b->get_type()) - return a->get_type() > b->get_type(); + return a->get_type() < b->get_type(); + else if (a->get_type() == SR_CHANNEL_DSO || a->get_type() == SR_CHANNEL_ANALOG) + return a->get_index() < b->get_index(); else return a->get_v_offset() < b->get_v_offset(); } @@ -434,13 +466,27 @@ void View::repeat_unshow() void View::frame_began() { - if (_session.get_device()->dev_inst()->mode == LOGIC) - _viewbottom->set_trig_time(_session.get_trigger_time()); +// if (_session.get_device()->dev_inst()->mode == LOGIC) +// _viewbottom->set_trig_time(_session.get_trigger_time()); _search_hit = false; _search_pos = 0; set_search_pos(_search_pos, _search_hit); } +void View::set_trig_time() +{ + if (!_trig_time_setted && _session.get_device()->dev_inst()->mode == LOGIC) { + _session.set_trigger_time(QDateTime::currentDateTime()); + _viewbottom->set_trig_time(_session.get_trigger_time()); + } + _trig_time_setted = true; +} + +bool View::trig_time_setted() +{ + return _trig_time_setted; +} + void View::receive_end() { if (_session.get_device()->dev_inst()->mode == LOGIC) { @@ -487,12 +533,14 @@ void View::set_trig_pos(int percent) void View::set_search_pos(uint64_t search_pos, bool hit) { //assert(search_pos >= 0); + QColor fore(QWidget::palette().color(QWidget::foregroundRole())); + fore.setAlpha(View::BackAlpha); const double time = search_pos * 1.0 / _session.cur_samplerate(); _search_pos = search_pos; _search_hit = hit; _search_cursor->set_index(search_pos); - _search_cursor->set_colour(hit ? Trace::dsLightBlue : Trace::dsGray); + _search_cursor->set_colour(hit ? View::Blue : fore); if (hit) { set_scale_offset(_scale, (time / _scale) - (get_view_width() / 2)); @@ -557,7 +605,7 @@ void View::update_scroll() { assert(_viewcenter); - const QSize areaSize = _viewcenter->size(); + const QSize areaSize = QSize(get_view_width(), get_view_height()); // Set the horizontal scroll bar int64_t length = 0; @@ -611,21 +659,24 @@ void View::update_scale_offset() viewport_update(); } -void View::mode_changed() +void View::dev_changed(bool close) { - const uint64_t sample_rate = _session.cur_samplerate(); - assert(sample_rate > 0); + if (!close) { + const uint64_t sample_rate = _session.cur_samplerate(); + assert(sample_rate > 0); - if (_session.get_device()->name().contains("virtual")) - _scale = WellSamplesPerPixel * 1.0 / sample_rate; - _scale = max(min(_scale, _maxscale), _minscale); + if (_session.get_device()->name().contains("virtual")) + _scale = WellSamplesPerPixel * 1.0 / sample_rate; + _scale = max(min(_scale, _maxscale), _minscale); + } - update_device_list(); + device_changed(close); } void View::signals_changed() { int total_rows = 0; + int label_size = 0; uint8_t max_height = MaxHeightUnit; vector< boost::shared_ptr > time_traces; vector< boost::shared_ptr > fft_traces; @@ -656,7 +707,7 @@ void View::signals_changed() _vsplitter->refresh(); // Find the _fft_viewport in the stack - std::list< Viewport *>::iterator iter = _viewport_list.begin(); + std::list< QWidget *>::iterator iter = _viewport_list.begin(); for(unsigned int i = 0; i < _viewport_list.size(); i++, iter++) if ((*iter) == _fft_viewport) break; @@ -671,10 +722,12 @@ void View::signals_changed() if (dynamic_pointer_cast(t) || t->enabled()) total_rows += t->rows_size(); + if (t->rows_size() != 0) + label_size++; } const double height = (_time_viewport->height() - - 2 * SignalMargin * time_traces.size()) * 1.0 / total_rows; + - 2 * SignalMargin * label_size) * 1.0 / total_rows; if (_session.get_device()->dev_inst()->mode == LOGIC) { GVariant* gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_MAX_HEIGHT_VALUE); @@ -686,7 +739,7 @@ void View::signals_changed() } else if (_session.get_device()->dev_inst()->mode == DSO) { _signalHeight = (_header->height() - horizontalScrollBar()->height() - - 2 * SignalMargin * time_traces.size()) * 1.0 / total_rows; + - 2 * SignalMargin * label_size) * 1.0 / total_rows; } else { _signalHeight = (int)((height <= 0) ? 1 : height); } @@ -695,6 +748,8 @@ void View::signals_changed() BOOST_FOREACH(boost::shared_ptr t, time_traces) { t->set_view(this); t->set_viewport(_time_viewport); + if (t->rows_size() == 0) + continue; const double traceHeight = _signalHeight*t->rows_size(); t->set_totalHeight((int)traceHeight); t->set_v_offset(next_v_offset + 0.5 * traceHeight + SignalMargin); @@ -704,6 +759,11 @@ void View::signals_changed() if ((dsoSig = dynamic_pointer_cast(t))) { dsoSig->set_scale(dsoSig->get_view_rect().height()); } + + boost::shared_ptr analogSig; + if ((analogSig = dynamic_pointer_cast(t))) { + analogSig->set_scale(analogSig->get_totalHeight()); + } } _time_viewport->clear_measure(); } @@ -777,6 +837,7 @@ int View::headerWidth() void View::resizeEvent(QResizeEvent*) { + reconstruct(); setViewportMargins(headerWidth(), RulerHeight, 0, 0); update_margins(); update_scroll(); @@ -986,15 +1047,15 @@ uint64_t View::get_cursor_samples(int index) void View::set_measure_en(int enable) { - BOOST_FOREACH(Viewport *viewport, _viewport_list) - viewport->set_measure_en(enable); + _time_viewport->set_measure_en(enable); + _fft_viewport->set_measure_en(enable); } void View::on_state_changed(bool stop) { if (stop) { - BOOST_FOREACH(Viewport *viewport, _viewport_list) - viewport->stop_trigger_timer(); + _time_viewport->stop_trigger_timer(); + _fft_viewport->stop_trigger_timer(); } update_scale_offset(); } @@ -1067,11 +1128,22 @@ void View::hide_calibration() _cali->hide(); } -void View::update_calibration() +void View::vDial_updated() { if (_cali->isVisible()) { _cali->set_device(_session.get_device()); } + boost::shared_ptr math_trace = _session.get_math_trace(); + if (math_trace && math_trace->enabled()) { + math_trace->update_vDial(); + } +} + +// -- lissajous figure +void View::show_lissajous(bool show) +{ + _show_lissajous = show; + signals_changed(); } void View::show_region(uint64_t start, uint64_t end, bool keep) @@ -1095,7 +1167,7 @@ void View::show_region(uint64_t start, uint64_t end, bool keep) void View::viewport_update() { _viewcenter->update(); - BOOST_FOREACH(Viewport *viewport, _viewport_list) + BOOST_FOREACH(QWidget *viewport, _viewport_list) viewport->update(); } @@ -1108,16 +1180,34 @@ void View::splitterMoved(int pos, int index) void View::reload() { - show_trig_cursor(false); + clear(); /* * if headerwidth not change, viewport height will not be updated * lead to a wrong signal height */ - if (_session.get_device()->dev_inst()->mode == LOGIC) - _viewbottom->setFixedHeight(StatusHeight); + reconstruct(); +} + +void View::clear() +{ + show_trig_cursor(false); + + if (_session.get_device()->dev_inst()->mode != DSO) { + show_xcursors(false); + } else { + if (!get_xcursorList().empty()) + show_xcursors(true); + } +} + +void View::reconstruct() +{ + if (_session.get_device()->dev_inst()->mode == DSO) + _viewbottom->setFixedHeight(DsoStatusHeight); else - _viewbottom->setFixedHeight(10); + _viewbottom->setFixedHeight(StatusHeight); + _viewbottom->reload(); } void View::repeat_show() @@ -1140,5 +1230,54 @@ bool View::get_dso_trig_moved() const return _time_viewport->get_dso_trig_moved(); } +/* + * horizental cursors + */ +bool View::xcursors_shown() +{ + return _show_xcursors; +} + +void View::show_xcursors(bool show) +{ + _show_xcursors = show; +} + +std::list& View::get_xcursorList() +{ + return _xcursorList; +} + +void View::add_xcursor(QColor color, double value0, double value1) +{ + XCursor *newXCursor = new XCursor(*this, color, value0, value1); + _xcursorList.push_back(newXCursor); + xcursor_update(); +} + +void View::del_xcursor(XCursor* xcursor) +{ + assert(xcursor); + + _xcursorList.remove(xcursor); + delete xcursor; + xcursor_update(); +} + +ViewStatus* View::get_viewstatus() +{ + return _viewbottom; +} + +bool View::back_ready() const +{ + return _back_ready; +} + +void View::set_back(bool ready) +{ + _back_ready = ready; +} + } // namespace view } // namespace pv diff --git a/DSView/pv/view/view.h b/DSView/pv/view/view.h old mode 100644 new mode 100755 index 466c5aa93cb7c60a427f3fa3049934d520db0738..ae132557549018f238d0d5f14569fba1802308a4 --- a/DSView/pv/view/view.h +++ b/DSView/pv/view/view.h @@ -41,8 +41,9 @@ #include "../data/signaldata.h" #include "../view/viewport.h" #include "cursor.h" +#include "xcursor.h" #include "signal.h" -#include "../widgets/viewstatus.h" +#include "viewstatus.h" namespace pv { @@ -50,6 +51,11 @@ namespace toolbars { class SamplingBar; } +namespace dialogs { + class Calibration; + class Lissajous; +} + class SigSession; namespace view { @@ -59,6 +65,7 @@ class DevMode; class Ruler; class Trace; class Viewport; +class LissajousFigure; class View : public QScrollArea { Q_OBJECT @@ -84,6 +91,16 @@ public: static const int MaxPixelsPerSample = 100; static const int StatusHeight = 20; + static const int DsoStatusHeight = 55; + + static const int ForeAlpha = 200; + static const int BackAlpha = 100; + static const QColor Red; + static const QColor Orange; + static const QColor Blue; + static const QColor Green; + static const QColor Purple; + static const QColor LightBlue; public: explicit View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget *parent = 0); @@ -163,6 +180,15 @@ public: uint64_t get_search_pos(); + /* + * horizental cursors + */ + bool xcursors_shown(); + void show_xcursors(bool show); + std::list& get_xcursorList(); + void add_xcursor(QColor color, double value0, double value1); + void del_xcursor(XCursor* xcursor); + /* * */ @@ -193,10 +219,19 @@ public: bool get_dso_trig_moved() const; + ViewStatus* get_viewstatus(); + + /* + * back paint status + */ + bool back_ready() const; + void set_back(bool ready); + signals: void hover_point_changed(); void cursor_update(); + void xcursor_update(); void cursor_moving(); void cursor_moved(); @@ -205,7 +240,7 @@ signals: void prgRate(int progress); - void update_device_list(); + void device_changed(bool close); void resize(); @@ -222,6 +257,9 @@ private: const boost::shared_ptr &a, const boost::shared_ptr &b); + void clear(); + void reconstruct(); + private: bool eventFilter(QObject *object, QEvent *event); @@ -237,17 +275,23 @@ public slots: void update_scale_offset(); void show_region(uint64_t start, uint64_t end, bool keep); // -- calibration - void update_calibration(); void hide_calibration(); void status_clear(); void repeat_unshow(); + // -- repeat void repeat_show(); // -- void timebase_changed(); // -- + void vDial_updated(); + // -- void update_hori_res(); + // -- + void set_trig_time(); + bool trig_time_setted(); + private slots: void h_scroll_value_changed(int value); @@ -268,11 +312,13 @@ private slots: // calibration for oscilloscope void show_calibration(); + // lissajous figure + void show_lissajous(bool show); void on_measure_updated(); void splitterMoved(int pos, int index); - void mode_changed(); + void dev_changed(bool close); private: @@ -280,12 +326,13 @@ private: pv::toolbars::SamplingBar *_sampling_bar; QWidget *_viewcenter; - widgets::ViewStatus *_viewbottom; + ViewStatus *_viewbottom; QSplitter *_vsplitter; Viewport * _time_viewport; Viewport * _fft_viewport; + LissajousFigure *_lissajous; Viewport *_active_viewport; - std::list _viewport_list; + std::list _viewport_list; std::map _trace_view_map; Ruler *_ruler; Header *_header; @@ -313,9 +360,16 @@ private: uint64_t _search_pos; bool _search_hit; + bool _show_xcursors; + std::list _xcursorList; + QPoint _hover_point; dialogs::Calibration *_cali; + bool _dso_auto; + bool _show_lissajous; + bool _back_ready; + bool _trig_time_setted; }; } // namespace view diff --git a/DSView/pv/view/viewport.cpp b/DSView/pv/view/viewport.cpp old mode 100644 new mode 100755 index 6bc37af7d44ea0499ae4b521905fe679b8656654..33e637f4ed3f512da1927a349001c4eb6e4c7096 --- a/DSView/pv/view/viewport.cpp +++ b/DSView/pv/view/viewport.cpp @@ -26,7 +26,7 @@ #include "signal.h" #include "dsosignal.h" #include "logicsignal.h" -#include "mathtrace.h" +#include "spectrumtrace.h" #include "../device/devinst.h" #include "../data/logic.h" #include "../data/logicsnapshot.h" @@ -70,7 +70,8 @@ Viewport::Viewport(View &parent, View_type type) : _dso_ym_valid(false), _waiting_trig(0), _dso_trig_moved(false), - _curs_moved(false) + _curs_moved(false), + _xcurs_moved(false) { setMouseTracking(true); setAutoFillBackground(true); @@ -90,9 +91,6 @@ Viewport::Viewport(View &parent, View_type type) : _drag_strength = 0; _drag_timer.setSingleShot(true); - _pixmap = new QPixmap(size()); - _pixmap->fill(Qt::transparent); - connect(&trigger_timer, SIGNAL(timeout()), this, SLOT(on_trigger_timer())); connect(&_drag_timer, SIGNAL(timeout()), @@ -100,6 +98,16 @@ Viewport::Viewport(View &parent, View_type type) : connect(&_view.session(), &SigSession::receive_data, this, &Viewport::set_receive_len); + + _cmenu = new QMenu(this); + QAction *yAction = _cmenu->addAction(tr("Add Y-cursor")); + QAction *xAction = _cmenu->addAction(tr("Add X-cursor")); + connect(yAction, SIGNAL(triggered(bool)), this, SLOT(add_cursor_y())); + connect(xAction, SIGNAL(triggered(bool)), this, SLOT(add_cursor_x())); + + setContextMenuPolicy(Qt::CustomContextMenu); + connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), + this, SLOT(show_contextmenu(const QPoint&))); } int Viewport::get_total_height() const @@ -132,17 +140,19 @@ void Viewport::paintEvent(QPaintEvent *event) QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &o, &p, this); - //p.begin(this); + QColor fore(QWidget::palette().color(QWidget::foregroundRole())); + QColor back(QWidget::palette().color(QWidget::backgroundRole())); + fore.setAlpha(View::ForeAlpha); + _view.set_back(false); const vector< boost::shared_ptr > traces(_view.get_traces(_type)); BOOST_FOREACH(const boost::shared_ptr t, traces) { assert(t); - t->paint_back(p, 0, _view.get_view_width()); - if (_view.session().get_device()->dev_inst()->mode == DSO) + t->paint_back(p, 0, _view.get_view_width(), fore, back); + if (_view.back_ready()) break; } - p.setRenderHint(QPainter::Antialiasing, false); if (_view.session().get_device()->dev_inst()->mode == LOGIC || _view.session().get_instant()) { switch(_view.session().get_capture_state()) { @@ -150,84 +160,123 @@ void Viewport::paintEvent(QPaintEvent *event) break; case SigSession::Stopped: - paintSignals(p); + paintSignals(p, fore, back); break; case SigSession::Running: if (_view.session().isRepeating() && !transfer_started) { _view.set_capture_status(); - paintSignals(p); + paintSignals(p, fore, back); } else if (_type == TIME_VIEW) { _view.repeat_unshow(); - p.setRenderHint(QPainter::Antialiasing); - paintProgress(p); - p.setRenderHint(QPainter::Antialiasing, false); + paintProgress(p, fore, back); } break; } } else { - paintSignals(p); + paintSignals(p, fore, back); } BOOST_FOREACH(const boost::shared_ptr t, traces) { assert(t); if (t->enabled()) - t->paint_fore(p, 0, _view.get_view_width()); + t->paint_fore(p, 0, _view.get_view_width(), fore, back); } - //p.setRenderHint(QPainter::Antialiasing, false); if (_view.get_signalHeight() != _curSignalHeight) _curSignalHeight = _view.get_signalHeight(); p.end(); } -void Viewport::paintSignals(QPainter &p) +void Viewport::paintSignals(QPainter &p, QColor fore, QColor back) { -// if (_view.session().get_data_lock()) -// return; const vector< boost::shared_ptr > traces(_view.get_traces(_type)); - if (_view.scale() != _curScale || - _view.offset() != _curOffset || - _view.get_signalHeight() != _curSignalHeight || - _need_update) { - _curScale = _view.scale(); - _curOffset = _view.offset(); - _curSignalHeight = _view.get_signalHeight(); - - //pixmap = QPixmap(size()); - //pixmap.fill(Qt::transparent); - if (_pixmap->size() == size()) { - _pixmap->fill(Qt::transparent); - QPainter dbp(_pixmap); + if (_view.session().get_device()->dev_inst()->mode == LOGIC) { + BOOST_FOREACH(const boost::shared_ptr t, traces) + { + assert(t); + if (t->enabled()) + t->paint_mid(p, 0, t->get_view_rect().right(), fore, back); + } + } else { + if (_view.scale() != _curScale || + _view.offset() != _curOffset || + _view.get_signalHeight() != _curSignalHeight || + _need_update) { + _curScale = _view.scale(); + _curOffset = _view.offset(); + _curSignalHeight = _view.get_signalHeight(); + + pixmap = QPixmap(size()); + pixmap.fill(Qt::transparent); + + QPainter dbp(&pixmap); dbp.initFrom(this); - //p.setRenderHint(QPainter::Antialiasing, false); BOOST_FOREACH(const boost::shared_ptr t, traces) { assert(t); if (t->enabled()) - t->paint_mid(dbp, 0, t->get_view_rect().right()); + t->paint_mid(dbp, 0, t->get_view_rect().right(), fore, back); } _need_update = false; } + p.drawPixmap(0, 0, pixmap); } - if (_pixmap->size() == size()) - p.drawPixmap(0, 0, *_pixmap); // plot cursors + //const QRect xrect = QRect(rect().left(), rect().top(), _view.get_view_width(), rect().height()); + const QRect xrect = _view.get_view_rect(); const double samples_per_pixel = _view.session().cur_samplerate() * _view.scale(); if (_view.cursors_shown() && _type == TIME_VIEW) { list::iterator i = _view.get_cursorList().begin(); int index = 0; while (i != _view.get_cursorList().end()) { const int64_t cursorX = (*i)->index()/samples_per_pixel - _view.offset(); - if (rect().contains(_view.hover_point().x(), _view.hover_point().y()) && + if (xrect.contains(_view.hover_point().x(), _view.hover_point().y()) && qAbs(cursorX - _view.hover_point().x()) <= HitCursorMargin) - (*i)->paint(p, rect(), 1, index); + (*i)->paint(p, xrect, 1, index); else - (*i)->paint(p, rect(), 0, index); + (*i)->paint(p, xrect, 0, index); + i++; + index++; + } + } + + if (_view.xcursors_shown() && _type == TIME_VIEW) { + list::iterator i = _view.get_xcursorList().begin(); + int index = 0; + bool hovered = false; + while (i != _view.get_xcursorList().end()) { + const double cursorX = xrect.left() + (*i)->value(XCursor::XCur_Y)*xrect.width(); + const double cursorY0 = xrect.top() + (*i)->value(XCursor::XCur_X0)*xrect.height(); + const double cursorY1 = xrect.top() + (*i)->value(XCursor::XCur_X1)*xrect.height(); + + if (!hovered && ((*i)->get_close_rect(xrect).contains(_view.hover_point()) || + (*i)->get_map_rect(xrect).contains(_view.hover_point()))) { + (*i)->paint(p, xrect, XCursor::XCur_All, index); + hovered = true; + } else if(!hovered && xrect.contains(_view.hover_point())) { + if (qAbs(cursorX - _view.hover_point().x()) <= HitCursorMargin && + _view.hover_point().y() > min(cursorY0, cursorY1) && + _view.hover_point().y() < max(cursorY0, cursorY1)) { + (*i)->paint(p, xrect, XCursor::XCur_Y, index); + hovered = true; + } else if (qAbs(cursorY0 - _view.hover_point().y()) <= HitCursorMargin) { + (*i)->paint(p, xrect, XCursor::XCur_X0, index); + hovered = true; + } else if (qAbs(cursorY1 - _view.hover_point().y()) <= HitCursorMargin) { + (*i)->paint(p, xrect, XCursor::XCur_X1, index); + hovered = true; + } else { + (*i)->paint(p, xrect, XCursor::XCur_None, index); + } + } else { + (*i)->paint(p, xrect, XCursor::XCur_None, index); + } + i++; index++; } @@ -235,26 +284,26 @@ void Viewport::paintSignals(QPainter &p) if (_type == TIME_VIEW) { if (_view.trig_cursor_shown()) { - _view.get_trig_cursor()->paint(p, rect(), 0, -1); + _view.get_trig_cursor()->paint(p, xrect, 0, -1); } if (_view.search_cursor_shown()) { const int64_t searchX = _view.get_search_cursor()->index()/samples_per_pixel - _view.offset(); - if (rect().contains(_view.hover_point().x(), _view.hover_point().y()) && + if (xrect.contains(_view.hover_point().x(), _view.hover_point().y()) && qAbs(searchX - _view.hover_point().x()) <= HitCursorMargin) - _view.get_search_cursor()->paint(p, rect(), 1, -1); + _view.get_search_cursor()->paint(p, xrect, 1, -1); else - _view.get_search_cursor()->paint(p, rect(), 0, -1); + _view.get_search_cursor()->paint(p, xrect, 0, -1); } // plot zoom rect if (_action_type == LOGIC_ZOOM) { p.setPen(Qt::NoPen); - p.setBrush(Trace::dsLightBlue); + p.setBrush(View::LightBlue); p.drawRect(QRectF(_mouse_down_point, _mouse_point)); } //plot measure arrow - paintMeasure(p); + paintMeasure(p, fore, back); //plot trigger information if (_view.session().get_device()->dev_inst()->mode == DSO && @@ -284,14 +333,16 @@ void Viewport::paintSignals(QPainter &p) type_str = "Trig'd"; } } - p.setPen(Trace::DARK_FORE); + p.setPen(fore); p.drawText(_view.get_view_rect(), Qt::AlignLeft | Qt::AlignTop, type_str); } } } -void Viewport::paintProgress(QPainter &p) +void Viewport::paintProgress(QPainter &p, QColor fore, QColor back) { + (void)back; + using pv::view::Signal; const uint64_t sample_limits = _view.session().cur_samplelimits(); @@ -299,12 +350,13 @@ void Viewport::paintProgress(QPainter &p) double progress = -(_sample_received * 1.0 / sample_limits * 360 * 16); int captured_progress = 0; + p.setRenderHint(QPainter::Antialiasing, true); p.setPen(Qt::gray); p.setBrush(Qt::NoBrush); const QPoint cenPos = QPoint(_view.get_view_width() / 2, height() / 2); const int radius = min(0.3 * _view.get_view_width(), 0.3 * height()); p.drawEllipse(cenPos, radius - 2, radius - 2); - p.setPen(QPen(Trace::dsGreen, 4, Qt::SolidLine)); + p.setPen(QPen(View::Green, 4, Qt::SolidLine)); p.drawArc(cenPos.x() - radius, cenPos.y() - radius, 2* radius, 2 * radius, 180 * 16, progress); p.setPen(Qt::gray); @@ -368,49 +420,58 @@ void Viewport::paintProgress(QPainter &p) const QPoint cenRightPos = QPoint(width / 2 + 0.05 * width, height() / 2); const int trigger_radius = min(0.02 * width, 0.02 * height()); + QColor foreBack = fore; + foreBack.setAlpha(View::BackAlpha); p.setPen(Qt::NoPen); - p.setBrush((timer_cnt % 3) == 0 ? Trace::dsLightBlue : Trace::dsGray); + p.setBrush((timer_cnt % 3) == 0 ? fore : foreBack); p.drawEllipse(cenLeftPos, trigger_radius, trigger_radius); - p.setBrush((timer_cnt % 3) == 1 ? Trace::dsLightBlue : Trace::dsGray); + p.setBrush((timer_cnt % 3) == 1 ? fore : foreBack); p.drawEllipse(cenPos, trigger_radius, trigger_radius); - p.setBrush((timer_cnt % 3) == 2 ? Trace::dsLightBlue : Trace::dsGray); + p.setBrush((timer_cnt % 3) == 2 ? fore : foreBack); p.drawEllipse(cenRightPos, trigger_radius, trigger_radius); bool triggered; if (_view.session().get_capture_status(triggered, captured_progress)){ - p.setPen(Trace::dsLightBlue); + p.setPen(View::Blue); QFont font=p.font(); font.setPointSize(10); font.setBold(true); p.setFont(font); QRect status_rect = QRect(cenPos.x() - radius, cenPos.y() + radius * 0.4, radius * 2, radius * 0.5); - if (triggered) + if (triggered) { p.drawText(status_rect, Qt::AlignCenter | Qt::AlignVCenter, tr("Triggered! ") + QString::number(captured_progress) + tr("% Captured")); - else + _view.set_trig_time(); + } else { p.drawText(status_rect, Qt::AlignCenter | Qt::AlignVCenter, tr("Waiting for Trigger! ") + QString::number(captured_progress) + tr("% Captured")); + } prgRate(captured_progress); } } else { + if (!_view.trig_time_setted()) + _view.set_trig_time(); + const int progress100 = ceil(progress / -3.6 / 16); - p.setPen(Trace::dsGreen); + p.setPen(View::Green); QFont font=p.font(); font.setPointSize(50); font.setBold(true); p.setFont(font); - p.drawText(rect(), Qt::AlignCenter | Qt::AlignVCenter, QString::number(progress100)+"%"); + p.drawText(_view.get_view_rect(), Qt::AlignCenter | Qt::AlignVCenter, QString::number(progress100)+"%"); prgRate(progress100); } - p.setPen(QPen(Trace::dsLightBlue, 4, Qt::SolidLine)); + p.setPen(QPen(View::Blue, 4, Qt::SolidLine)); const int int_radius = max(radius - 4, 0); p.drawArc(cenPos.x() - int_radius, cenPos.y() - int_radius, 2* int_radius, 2 * int_radius, 180 * 16, -captured_progress*3.6*16); QFont font; p.setFont(font); + + p.setRenderHint(QPainter::Antialiasing, false); } void Viewport::mousePressEvent(QMouseEvent *event) @@ -422,28 +483,6 @@ void Viewport::mousePressEvent(QMouseEvent *event) _drag_strength = 0; _time.restart(); - if (event->button() == Qt::LeftButton) { - const vector< boost::shared_ptr > sigs(_view.session().get_signals()); - BOOST_FOREACH(const boost::shared_ptr s, sigs) { - assert(s); - if (!s->enabled()) - continue; - boost::shared_ptr dsoSig; - if ((dsoSig = dynamic_pointer_cast(s))) { - if (dsoSig->get_ms_show_hover()) { - dsoSig->set_ms_show(!dsoSig->get_ms_show()); - break; - } else if (dsoSig->get_ms_gear_hover()) { - pv::dialogs::DsoMeasure dsoMeasureDialog(this, dsoSig); - dsoMeasureDialog.exec(); - break; - } - } - } - - update(); - } - if (_action_type == NO_ACTION && event->button() == Qt::RightButton && _view.session().get_capture_state() == SigSession::Stopped) { @@ -481,7 +520,7 @@ void Viewport::mousePressEvent(QMouseEvent *event) event->button() == Qt::LeftButton) { uint64_t sample_rate = _view.session().cur_samplerate(); const double samples_per_pixel = sample_rate * _view.scale(); - if (_view.search_cursor_shown()) { + if (_action_type == NO_ACTION && _view.search_cursor_shown()) { const int64_t searchX = _view.get_search_cursor()->index()/samples_per_pixel - _view.offset(); if (_view.get_search_cursor()->grabbed()) { _view.get_ruler()->rel_grabbed_cursor(); @@ -490,7 +529,7 @@ void Viewport::mousePressEvent(QMouseEvent *event) _action_type = CURS_MOVE; } } - if (_view.cursors_shown()) { + if (_action_type == NO_ACTION && _view.cursors_shown()) { list::iterator i = _view.get_cursorList().begin(); while (i != _view.get_cursorList().end()) { const int64_t cursorX = (*i)->index()/samples_per_pixel - _view.offset(); @@ -504,6 +543,66 @@ void Viewport::mousePressEvent(QMouseEvent *event) i++; } } + if (_action_type == NO_ACTION && _view.xcursors_shown()) { + list::iterator i = _view.get_xcursorList().begin(); + const QRect xrect = _view.get_view_rect(); + while (i != _view.get_xcursorList().end()) { + const double cursorX = xrect.left() + (*i)->value(XCursor::XCur_Y)*xrect.width(); + const double cursorY0 = xrect.top() + (*i)->value(XCursor::XCur_X0)*xrect.height(); + const double cursorY1 = xrect.top() + (*i)->value(XCursor::XCur_X1)*xrect.height(); + if ((*i)->get_close_rect(xrect).contains(_view.hover_point())) { + _view.del_xcursor(*i); + if (_view.get_xcursorList().empty()) + _view.show_xcursors(false); + break; + } else if ((*i)->get_map_rect(xrect).contains(_view.hover_point())) { + vector< boost::shared_ptr > sigs(_view.session().get_signals()); + vector< boost::shared_ptr >::iterator s = sigs.begin(); + bool sig_looped = ((*i)->channel() == NULL); + bool no_dsoSig = true; + while (1) { + boost::shared_ptr dsoSig; + if ((dsoSig = dynamic_pointer_cast(*s)) && + dsoSig->enabled()) { + no_dsoSig = false; + if (sig_looped) { + (*i)->set_channel(dsoSig); + break; + } else if (dsoSig == (*i)->channel()) { + sig_looped = true; + } + } + s++; + if (s == sigs.end()) { + if (no_dsoSig) { + (*i)->set_channel(NULL); + break; + } + sig_looped = true; + s = sigs.begin(); + } + } + break; + }else if ((*i)->grabbed() != XCursor::XCur_None) { + (*i)->set_grabbed((*i)->grabbed(), false); + } else if (qAbs(cursorX - _view.hover_point().x()) <= HitCursorMargin && + _view.hover_point().y() > min(cursorY0, cursorY1) && + _view.hover_point().y() < max(cursorY0, cursorY1)) { + (*i)->set_grabbed(XCursor::XCur_Y, true); + _action_type = CURS_MOVE; + break; + } else if (qAbs(cursorY0 - _view.hover_point().y()) <= HitCursorMargin) { + (*i)->set_grabbed(XCursor::XCur_X0, true); + _action_type = CURS_MOVE; + break; + } else if (qAbs(cursorY1 - _view.hover_point().y()) <= HitCursorMargin) { + (*i)->set_grabbed(XCursor::XCur_X1, true); + _action_type = CURS_MOVE; + break; + } + i++; + } + } } } @@ -520,7 +619,7 @@ void Viewport::mouseMoveEvent(QMouseEvent *event) } _drag_strength = (_mouse_down_point - event->pos()).x(); } else if (_type == FFT_VIEW) { - BOOST_FOREACH(const boost::shared_ptr t, _view.session().get_math_signals()) { + BOOST_FOREACH(const boost::shared_ptr t, _view.session().get_spectrum_traces()) { assert(t); if(t->enabled()) { double delta = (_mouse_point - event->pos()).x(); @@ -538,7 +637,7 @@ void Viewport::mouseMoveEvent(QMouseEvent *event) if (_drag_sig) { boost::shared_ptr dsoSig; if ((dsoSig = dynamic_pointer_cast(_drag_sig))) { - dsoSig->set_trig_vpos(event->pos().y(), true); + dsoSig->set_trig_vpos(event->pos().y()); _dso_trig_moved = true; } } @@ -592,6 +691,25 @@ void Viewport::mouseMoveEvent(QMouseEvent *event) _view.cursor_moving(); _curs_moved = true; + } else { + if (_view.xcursors_shown()) { + list::iterator i = _view.get_xcursorList().begin(); + const QRect xrect = _view.get_view_rect(); + while (i != _view.get_xcursorList().end()) { + if ((*i)->grabbed() != XCursor::XCur_None) { + if ((*i)->grabbed() == XCursor::XCur_Y) { + double rate = (_view.hover_point().x() - xrect.left()) * 1.0 / xrect.width(); + (*i)->set_value((*i)->grabbed(), min(rate, 1.0)); + } else { + double rate = (_view.hover_point().y() - xrect.top()) * 1.0 / xrect.height(); + (*i)->set_value((*i)->grabbed(), max(rate, 0.0)); + } + _xcurs_moved = true; + break; + } + i++; + } + } } } } @@ -751,6 +869,15 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event) _view.cursor_moved(); _curs_moved = false; } + if (_xcurs_moved && event->button() == Qt::LeftButton) { + _action_type = NO_ACTION; + list::iterator i = _view.get_xcursorList().begin(); + while (i != _view.get_xcursorList().end()) { + (*i)->rel_grabbed(); + i++; + } + _xcurs_moved = false; + } } else if (_action_type == LOGIC_EDGE) { _action_type = NO_ACTION; _edge_rising = 0; @@ -799,7 +926,9 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event) void Viewport::mouseDoubleClickEvent(QMouseEvent *event) { assert (event); - (void)event; + + if (!_view.get_view_rect().contains(event->pos())) + return; if (_view.session().get_device()->dev_inst()->mode == LOGIC && _view.session().get_capture_state() == SigSession::Stopped) { @@ -862,6 +991,29 @@ void Viewport::mouseDoubleClickEvent(QMouseEvent *event) break; } } +// } else if (_view.session().get_device()->dev_inst()->mode == DSO) { +// if (event->button() == Qt::RightButton) { +// double ypos = (event->pos().y() - _view.get_view_rect().top()) * 1.0 / _view.get_view_height(); +// _view.add_xcursor(view::Ruler::CursorColor[_view.get_cursorList().size() % 8], ypos, ypos); +// _view.show_xcursors(true); +// } +// } else if (event->button() == Qt::LeftButton) { +// uint64_t index; +// const uint64_t sample_rate = _view.session().cur_samplerate(); +// const double curX = event->pos().x(); +// index = (_view.offset() + curX) * _view.scale() * sample_rate;; +// _view.add_cursor(view::Ruler::CursorColor[_view.get_cursorList().size() % 8], index); +// _view.show_cursors(true); +// } + } else if (_view.session().get_device()->dev_inst()->mode == ANALOG) { + if (event->button() == Qt::LeftButton) { + uint64_t index; + const uint64_t sample_rate = _view.session().cur_samplerate(); + const double curX = event->pos().x(); + index = (_view.offset() + curX) * _view.scale() * sample_rate;; + _view.add_cursor(view::Ruler::CursorColor[_view.get_cursorList().size() % 8], index); + _view.show_cursors(true); + } } } @@ -870,7 +1022,7 @@ void Viewport::wheelEvent(QWheelEvent *event) assert(event); if (_type == FFT_VIEW) { - BOOST_FOREACH(const boost::shared_ptr t, _view.session().get_math_signals()) { + BOOST_FOREACH(const boost::shared_ptr t, _view.session().get_spectrum_traces()) { assert(t); if(t->enabled()) { t->zoom(event->delta() / 80, event->x()); @@ -930,9 +1082,7 @@ void Viewport::leaveEvent(QEvent *) void Viewport::resizeEvent(QResizeEvent*) { - if (_pixmap) - delete _pixmap; - _pixmap = new QPixmap(size()); + } void Viewport::set_receive_len(quint64 length) @@ -1023,23 +1173,34 @@ void Viewport::measure() _cur_aftY = logicSig->get_y(); _edge_hit = true; break; + } else { + _cur_preX = _edge_start / samples_per_pixel - _view.offset(); + _cur_aftX = _view.hover_point().x(); + _cur_aftY = _view.hover_point().y(); + _edge_end = (_cur_aftX + _view.offset()) * samples_per_pixel; + _edge_hit = false; } - _cur_preX = _edge_start / samples_per_pixel - _view.offset(); - _cur_aftX = _view.hover_point().x(); - _cur_aftY = _view.hover_point().y(); - _edge_hit = false; } } else if ((dsoSig = dynamic_pointer_cast(s))) { - if (_measure_en && dsoSig->measure(_view.hover_point())) { - _measure_type = DSO_VALUE; - break; - } else { - _measure_type = NO_MEASURE; + if (dsoSig->enabled()) { + if (_measure_en && dsoSig->measure(_view.hover_point())) { + _measure_type = DSO_VALUE; + } else { + _measure_type = NO_MEASURE; + } } } } + const boost::shared_ptr mathTrace(_view.session().get_math_trace()); + if (mathTrace && mathTrace->enabled()) { + if (_measure_en && mathTrace->measure(_view.hover_point())) { + _measure_type = DSO_VALUE; + } else { + _measure_type = NO_MEASURE; + } + } } else if (_type == FFT_VIEW) { - BOOST_FOREACH(const boost::shared_ptr t, _view.session().get_math_signals()) { + BOOST_FOREACH(const boost::shared_ptr t, _view.session().get_spectrum_traces()) { assert(t); if(t->enabled()) { t->measure(_mouse_point); @@ -1050,12 +1211,13 @@ void Viewport::measure() measure_updated(); } -void Viewport::paintMeasure(QPainter &p) +void Viewport::paintMeasure(QPainter &p, QColor fore, QColor back) { + QColor active_color = back.black() > 0x80 ? View::Orange : View::Purple; _hover_hit = false; if (_action_type == NO_ACTION && _measure_type == LOGIC_FREQ) { - p.setPen(QColor(17, 133, 209, 255)); + p.setPen(active_color); p.drawLine(QLineF(_cur_preX, _cur_midY, _cur_aftX, _cur_midY)); p.drawLine(QLineF(_cur_preX, _cur_midY, _cur_preX + 2, _cur_midY - 2)); p.drawLine(QLineF(_cur_preX, _cur_midY, _cur_preX + 2, _cur_midY + 2)); @@ -1094,10 +1256,10 @@ void Viewport::paintMeasure(QPainter &p) QRectF measure4_rect = QRectF(org_pos.x(), org_pos.y()+60, (double)typical_width, 20.0); p.setPen(Qt::NoPen); - p.setBrush(QColor(17, 133, 209, 150)); + p.setBrush(View::LightBlue); p.drawRect(measure_rect); - p.setPen(Qt::black); + p.setPen(active_color); p.drawText(measure1_rect, Qt::AlignRight | Qt::AlignVCenter, tr("Width: ") + _mm_width); p.drawText(measure2_rect, Qt::AlignRight | Qt::AlignVCenter, @@ -1118,53 +1280,11 @@ void Viewport::paintMeasure(QPainter &p) uint64_t index; double value; QPointF hpoint; - const int arrow_size = 5; - const int mark_radius = 10; - const int mark_width = 20; - const int mark_cursor_height = 30; if (dsoSig->get_hover(index, hpoint, value)) { - p.setPen(dsoSig->get_colour()); - const QRectF hpoint_rect = QRectF(hpoint.x()-mark_radius/2, hpoint.y()-mark_radius/2, mark_radius, mark_radius); - if (hpoint_rect.contains(_view.hover_point())) { - p.setBrush(dsoSig->get_colour()); - const int cursor_up = hpoint.y()-mark_cursor_height; - const int cursor_dn = hpoint.y()+mark_cursor_height; - const int cursor_lf = hpoint.x()-arrow_size; - const int cursor_md = hpoint.x(); - const int cursor_rt = hpoint.x()+arrow_size; - - const QPointF up_arrow[3] = { - QPointF(cursor_lf, cursor_up+arrow_size), - QPointF(cursor_md, cursor_up), - QPointF(cursor_rt, cursor_up+arrow_size), - }; - const QPointF dn_arrow[3] = { - QPointF(cursor_lf, cursor_dn-arrow_size), - QPointF(cursor_md, cursor_dn), - QPointF(cursor_rt, cursor_dn-arrow_size), - }; - p.drawPolyline(up_arrow, 3); - p.drawPolyline(dn_arrow, 3); - p.drawLine(cursor_md, cursor_up, cursor_md, cursor_dn); - _hover_hit = true; - _hover_sig_index = dsoSig->get_index(); - _hover_sig_value = value; - _hover_index = index; - } else { - p.setBrush(Qt::NoBrush); - } - p.drawEllipse(hpoint, mark_radius, mark_radius); - QString value_c = abs(value) > 1000 ? QString::number(value/1000.0, 'f', 2) + "V" : QString::number(value, 'f', 2) + "mV"; - int value_width = p.boundingRect(0, 0, INT_MAX, INT_MAX, - Qt::AlignLeft | Qt::AlignTop, value_c).width(); - const bool right = dsoSig->get_index()%2 ? hpoint.x() < value_width : hpoint.x() < _view.get_view_width() - value_width; - const bool up = hpoint.y() > 50; - const QPointF hpoint_sec = QPointF(hpoint.x() - (right ? -mark_width : mark_width), hpoint.y() - (up ? mark_width : -mark_width)); - p.drawLine(hpoint, hpoint_sec); - p.drawLine(hpoint_sec, QPointF(hpoint_sec.x() + (right ? value_width : -value_width), hpoint_sec.y())); - p.drawText(QRectF(right ? hpoint_sec.x() : hpoint_sec.x() - value_width, hpoint_sec.y() - mark_width, value_width, mark_width), - Qt::AlignLeft | Qt::AlignBottom, - value_c); + p.setPen(QPen(fore, 1, Qt::DashLine)); + p.setBrush(Qt::NoBrush); + p.drawLine(hpoint.x(), dsoSig->get_view_rect().top(), + hpoint.x(), dsoSig->get_view_rect().bottom()); } } } @@ -1303,8 +1423,7 @@ void Viewport::paintMeasure(QPainter &p) } if (_action_type == LOGIC_EDGE) { - p.setPen(QColor(17, 133, 209, 255)); - + p.setPen(active_color); p.drawLine(QLineF(_cur_preX, _cur_midY-5, _cur_preX, _cur_midY+5)); p.drawLine(QLineF(_cur_aftX, _cur_midY-5, _cur_aftX, _cur_midY+5)); p.drawLine(QLineF(_cur_preX, _cur_midY, _cur_aftX, _cur_midY)); @@ -1316,7 +1435,7 @@ void Viewport::paintMeasure(QPainter &p) typical_width = max(typical_width, p.boundingRect(0, 0, INT_MAX, INT_MAX, Qt::AlignLeft | Qt::AlignTop, _em_falling).width()); - typical_width = typical_width + 30; + typical_width = typical_width + 60; const double width = _view.get_view_width(); const double height = _view.viewport()->height(); @@ -1331,10 +1450,10 @@ void Viewport::paintMeasure(QPainter &p) QRectF measure3_rect = QRectF(org_pos.x(), org_pos.y()+40, (double)typical_width, 20.0); p.setPen(Qt::NoPen); - p.setBrush(QColor(17, 133, 209, 150)); + p.setBrush(View::LightBlue); p.drawRect(measure_rect); - p.setPen(Qt::black); + p.setPen(active_color); p.drawText(measure1_rect, Qt::AlignRight | Qt::AlignVCenter, _em_edges); p.drawText(measure2_rect, Qt::AlignRight | Qt::AlignVCenter, _em_rising); p.drawText(measure3_rect, Qt::AlignRight | Qt::AlignVCenter, _em_falling); @@ -1342,7 +1461,8 @@ void Viewport::paintMeasure(QPainter &p) } if (_action_type == LOGIC_JUMP) { - p.setPen(QColor(238, 178, 17, 255)); + p.setPen(active_color); + p.setBrush(Qt::NoBrush); const QPoint pre_points[] = { QPoint(_cur_preX, _cur_preY), QPoint(_cur_preX-1, _cur_preY-1), @@ -1369,25 +1489,32 @@ void Viewport::paintMeasure(QPainter &p) QPoint(_cur_aftX+2, _cur_aftY+2), }; p.drawPoints(aft_points, countof(aft_points)); + } + int64_t delta = max(_edge_start, _edge_end) - min(_edge_start, _edge_end); + QString delta_text = _view.get_index_delta(_edge_start, _edge_end) + + "/" + QString::number(delta); + QFontMetrics fm = this->fontMetrics(); + const int rectW = fm.width(delta_text) + 60; + const int rectH = fm.height() + 10; + //const int rectY = (_cur_aftY >= _cur_preY) ? _cur_preY_top : _cur_preY_bottom; + //const int rectX = (_cur_aftX >= _cur_preX) ? _cur_preX : _cur_preX - rectW; + const int rectY = (height() - _view.hover_point().y() < rectH + 20) ? _view.hover_point().y() - 10 - rectH : _view.hover_point().y() + 20; + const int rectX = (width() - _view.hover_point().x() < rectW) ? _view.hover_point().x() - rectW : _view.hover_point().x(); + QRectF jump_rect = QRectF(rectX, rectY, rectW, rectH); - int64_t delta = max(_edge_start, _edge_end) - min(_edge_start, _edge_end); - QString delta_text = _view.get_index_delta(_edge_start, _edge_end) + - "/" + QString::number(delta); - QFontMetrics fm = this->fontMetrics(); - const int rectW = fm.width(delta_text); - const int rectY = (_cur_aftY >= _cur_preY) ? _cur_preY_top : _cur_preY_bottom; - const int rectX = (_cur_aftX >= _cur_preX) ? _cur_preX : _cur_preX - rectW; - QRectF jump_rect = QRectF(rectX, rectY, rectW, 10); - p.drawText(jump_rect, Qt::AlignCenter | Qt::AlignVCenter, delta_text); + p.setPen(Qt::NoPen); + p.setBrush(View::LightBlue); + p.drawRect(jump_rect); - } + p.setPen(active_color); + p.setBrush(Qt::NoBrush); + p.drawText(jump_rect, Qt::AlignCenter | Qt::AlignVCenter, delta_text); QPainterPath path(QPoint(_cur_preX, _cur_preY)); QPoint c1((_cur_preX+_cur_aftX)/2, _cur_preY); QPoint c2((_cur_preX+_cur_aftX)/2, _cur_aftY); path.cubicTo(c1, c2, QPoint(_cur_aftX, _cur_aftY)); p.drawPath(path); - } } } @@ -1481,5 +1608,34 @@ bool Viewport::get_dso_trig_moved() const return _dso_trig_moved; } +void Viewport::show_contextmenu(const QPoint& pos) +{ + if(_cmenu && + _view.session().get_device()->dev_inst()->mode == DSO) + { + _cur_preX = pos.x(); + _cur_preY = pos.y(); + _cmenu->exec(QCursor::pos()); + } +} + +void Viewport::add_cursor_y() +{ + uint64_t index; + const uint64_t sample_rate = _view.session().cur_samplerate(); + //const double curX = _menu_pos.x(); + index = (_view.offset() + _cur_preX) * _view.scale() * sample_rate;; + _view.add_cursor(view::Ruler::CursorColor[_view.get_cursorList().size() % 8], index); + _view.show_cursors(true); +} + +void Viewport::add_cursor_x() +{ + double ypos = (_cur_preY - _view.get_view_rect().top()) * 1.0 / _view.get_view_height(); + _view.add_xcursor(view::Ruler::CursorColor[_view.get_cursorList().size() % 8], ypos, ypos); + _view.show_xcursors(true); +} + + } // namespace view } // namespace pv diff --git a/DSView/pv/view/viewport.h b/DSView/pv/view/viewport.h old mode 100644 new mode 100755 index 005d1c325d9f24be3b76191a36e4f816bdffb410..8773c5e30a1bee4d95bbc2b18b52573083ea8a14 --- a/DSView/pv/view/viewport.h +++ b/DSView/pv/view/viewport.h @@ -87,7 +87,7 @@ public: public: explicit Viewport(View &parent, View_type type); - int get_total_height() const; + int get_total_height() const; QPoint get_mouse_point() const; @@ -110,17 +110,17 @@ protected: void paintEvent(QPaintEvent *event); private: - void mousePressEvent(QMouseEvent *event); - void mouseMoveEvent(QMouseEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); void mouseDoubleClickEvent(QMouseEvent *event); - void wheelEvent(QWheelEvent *event); + void wheelEvent(QWheelEvent *event); void leaveEvent(QEvent *); void resizeEvent(QResizeEvent *e); - void paintSignals(QPainter& p); - void paintProgress(QPainter& p); - void paintMeasure(QPainter &p); + void paintSignals(QPainter& p, QColor fore, QColor back); + void paintProgress(QPainter& p, QColor fore, QColor back); + void paintMeasure(QPainter &p, QColor fore, QColor back); void measure(); @@ -129,6 +129,10 @@ private slots: void on_drag_timer(); void set_receive_len(quint64 length); + void show_contextmenu(const QPoint& pos); + void add_cursor_x(); + void add_cursor_y(); + public slots: void show_wait_trigger(); void unshow_wait_trigger(); @@ -142,11 +146,12 @@ private: View_type _type; bool _need_update; - QPixmap *_pixmap; + QPixmap pixmap; + QMenu *_cmenu; uint64_t _sample_received; QPoint _mouse_point; - QPoint _mouse_down_point; + QPoint _mouse_down_point; int64_t _mouse_down_offset; double _curScale; int64_t _curOffset; @@ -211,6 +216,7 @@ private: int _waiting_trig; bool _dso_trig_moved; bool _curs_moved; + bool _xcurs_moved; }; } // namespace view diff --git a/DSView/pv/view/viewstatus.cpp b/DSView/pv/view/viewstatus.cpp new file mode 100755 index 0000000000000000000000000000000000000000..d5578a9680145bdd1d9f80e3309e3b738267a3de --- /dev/null +++ b/DSView/pv/view/viewstatus.cpp @@ -0,0 +1,247 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2016 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "viewstatus.h" + +#include +#include +#include +#include +#include + +#include "../view/trace.h" +#include "../sigsession.h" +#include "../device/devinst.h" +#include "../view/view.h" +#include "../view/trace.h" +#include "../dialogs/dsomeasure.h" + +using namespace boost; +using namespace std; + +namespace pv { +namespace view { + +ViewStatus::ViewStatus(SigSession &session, View &parent) : + QWidget(&parent), + _session(session), + _view(parent), + _hit_rect(-1), + _last_sig_index(-1) +{ +} + +void ViewStatus::paintEvent(QPaintEvent *) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); + + QColor fore(QWidget::palette().color(QWidget::foregroundRole())); + if (_session.get_device()->dev_inst()->mode == LOGIC) { + fore.setAlpha(View::ForeAlpha); + p.setPen(fore); + p.drawText(this->rect(), Qt::AlignLeft | Qt::AlignVCenter, _rle_depth); + p.drawText(this->rect(), Qt::AlignRight | Qt::AlignVCenter, _trig_time); + + p.setPen(Qt::NoPen); + p.setBrush(View::Blue); + p.drawRect(this->rect().left(), this->rect().bottom() - 3, + _session.get_repeat_hold() * this->rect().width() / 100, 3); + + p.setPen(View::Blue); + p.drawText(this->rect(), Qt::AlignCenter | Qt::AlignVCenter, _capture_status); + } else if (_session.get_device()->dev_inst()->mode == DSO) { + fore.setAlpha(View::BackAlpha); + for(size_t i = 0; i < _mrects.size(); i++) { + int sig_index = std::get<1>(_mrects[i]); + boost::shared_ptr dsoSig = NULL; + const vector< boost::shared_ptr > sigs(_session.get_signals()); + BOOST_FOREACH(const boost::shared_ptr s, sigs) { + assert(s); + if (!s->enabled()) + continue; + if ((dsoSig = dynamic_pointer_cast(s))) { + if (sig_index == dsoSig->get_index()) + break; + else + dsoSig = NULL; + } + } + + bool active = dsoSig && dsoSig->enabled(); + const QRect rect = std::get<0>(_mrects[i]); + p.setPen(Qt::NoPen); + p.setBrush(active ? dsoSig->get_colour() : fore); + p.drawRect(QRect(rect.topLeft(), QSize(10, rect.height()))); + + QPixmap msPix(pv::dialogs::DsoMeasure::get_ms_icon(std::get<2>(_mrects[i]))); + QBitmap msMask = msPix.createMaskFromColor(QColor("black"), Qt::MaskOutColor); + msPix.fill(active ? dsoSig->get_colour() : fore); + msPix.setMask(msMask); + p.drawPixmap(QRect(rect.left()+10, rect.top(), rect.height(), rect.height()), + msPix); + + p.setPen(((int)i == _hit_rect) ? View::Blue : + active ? dsoSig->get_colour() : fore); + p.setBrush(Qt::NoBrush); + p.drawRect(rect); + + enum DSO_MEASURE_TYPE mtype = std::get<2>(_mrects[i]); + if (active && (mtype != DSO_MS_BEGIN)) { + QString title = pv::dialogs::DsoMeasure::get_ms_text(std::get<2>(_mrects[i])) + ":"; + title += dsoSig->get_measure(mtype); + int width = p.boundingRect(rect, title).width(); + p.drawText(QRect(rect.left()+10+rect.height(), rect.top(), width, rect.height()), + Qt::AlignLeft | Qt::AlignVCenter, title); + } else { + p.drawText(rect, Qt::AlignCenter | Qt::AlignVCenter, tr("Measure") + QString::number(i)); + } + } + } +} + +void ViewStatus::clear() +{ + _trig_time.clear(); + _rle_depth.clear(); + _capture_status.clear(); + update(); +} + +void ViewStatus::reload() +{ + const int COLUMN = 5; + const int ROW = 2; + const int MARGIN = 3; + if (_session.get_device()->dev_inst()->mode == DSO) + { + const double width = _view.get_view_width() * 1.0 / COLUMN; + const int height = (this->height() - 2*MARGIN) / ROW; + for (size_t i = 0; i < COLUMN*ROW; i++) { + QRect rect(this->rect().left() + (i%COLUMN)*width, + this->rect().top() + (i/COLUMN+1)*MARGIN + (i/COLUMN)*height, + width-MARGIN, height); + if (_mrects.size() <= i) { + std::tuple rect_tuple; + std::get<0>(rect_tuple) = rect; + std::get<1>(rect_tuple) = -1; + std::get<2>(rect_tuple) = DSO_MS_BEGIN; + _mrects.push_back(rect_tuple); + } else { + std::get<0>(_mrects[i]) = rect; + } + } + } + update(); +} + +void ViewStatus::repeat_unshow() +{ + _capture_status.clear(); + update(); +} + +void ViewStatus::set_trig_time(QDateTime time) +{ + _trig_time = tr("Trigger Time: ") + time.toString("yyyy-MM-dd hh:mm:ss"); +} + +void ViewStatus::set_rle_depth(uint64_t depth) +{ + _rle_depth = QString::number(depth) + tr(" Samples Captured!"); +} + +void ViewStatus::set_capture_status(bool triggered, int progess) +{ + if (triggered) { + _capture_status = tr("Triggered! ") + QString::number(progess) + tr("% Captured"); + } else { + _capture_status = tr("Waiting for Trigger! ") + QString::number(progess) + tr("% Captured"); + } +} + +void ViewStatus::mousePressEvent(QMouseEvent *event) +{ + assert(event); + + if (event->button() == Qt::LeftButton) { + //BOOST_FOREACH(QRect rect, std::get<0>(_mrects)) { + for(size_t i = 0; i < _mrects.size(); i++) { + const QRect rect = std::get<0>(_mrects[i]); + if (rect.contains(event->pos())) { + _hit_rect = (int)i; + pv::dialogs::DsoMeasure dsoMeasureDialog(_session, _view, i, _last_sig_index); + dsoMeasureDialog.exec(); + break; + } + } + update(); + } +} + +void ViewStatus::set_measure(unsigned int index, bool canceled, + int sig_index, enum DSO_MEASURE_TYPE ms_type) +{ + _hit_rect = -1; + if (!canceled && index < _mrects.size()) { + _last_sig_index = sig_index; + std::get<1>(_mrects[index]) = sig_index; + std::get<2>(_mrects[index]) = ms_type; + } + update(); +} + +QJsonArray ViewStatus::get_session() +{ + QJsonArray measureVar; + for(int i = 0; i < (int)_mrects.size(); i++) { + const int index = std::get<1>(_mrects[i]); + if (index != -1) { + QJsonObject m_obj; + m_obj["site"] = i; + m_obj["index"] = index; + m_obj["type"] = (int)std::get<2>(_mrects[i]); + measureVar.append(m_obj); + } + } + + return measureVar; +} + +void ViewStatus::load_session(QJsonArray measure_array) +{ + if (_session.get_device()->dev_inst()->mode != DSO || + measure_array.empty()) + return; + + foreach (const QJsonValue &measure_value, measure_array) { + QJsonObject m_obj = measure_value.toObject(); + int index = m_obj["site"].toInt(); + int sig_index = m_obj["index"].toInt(); + enum DSO_MEASURE_TYPE ms_type = DSO_MEASURE_TYPE(m_obj["type"].toInt()); + set_measure(index, false, sig_index, ms_type); + } +} + +} // namespace view +} // namespace pv diff --git a/DSView/pv/widgets/viewstatus.h b/DSView/pv/view/viewstatus.h old mode 100644 new mode 100755 similarity index 64% rename from DSView/pv/widgets/viewstatus.h rename to DSView/pv/view/viewstatus.h index a41f9d3119dc0a39324a3a44554029a42c2ce877..804dfbfa8beaa11d98761ac660f91700fc2cd0c4 --- a/DSView/pv/widgets/viewstatus.h +++ b/DSView/pv/view/viewstatus.h @@ -19,31 +19,49 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef DSVIEW_PV_WIDGETS_VIEWSTATUS_H -#define DSVIEW_PV_WIDGETS_VIEWSTATUS_H +#ifndef DSVIEW_PV_VIEW_VIEWSTATUS_H +#define DSVIEW_PV_VIEW_VIEWSTATUS_H #include #include #include +#include +#include + +#include +#include + +#include namespace pv { class SigSession; -namespace widgets { +namespace view { +class View; +class DsoSignal; + class ViewStatus : public QWidget { Q_OBJECT public: - explicit ViewStatus(SigSession &session, QWidget *parent = 0); + ViewStatus(SigSession &session, View &parent); void paintEvent(QPaintEvent *); + void mousePressEvent(QMouseEvent *); + + void set_measure(unsigned int index, bool canceled, + int sig_index, enum DSO_MEASURE_TYPE ms_type); + + QJsonArray get_session(); + void load_session(QJsonArray meausre_array); signals: public slots: void clear(); + void reload(); void repeat_unshow(); void set_trig_time(QDateTime time); void set_rle_depth(uint64_t depth); @@ -51,13 +69,18 @@ public slots: private: SigSession &_session; + View &_view; + int _hit_rect; QString _trig_time; QString _rle_depth; QString _capture_status; + + int _last_sig_index; + std::vector> _mrects; }; -} // namespace widgets +} // namespace view } // namespace pv -#endif // DSVIEW_PV_WIDGETS_VIEWSTATUS_H +#endif // DSVIEW_PV_VIEW_VIEWSTATUS_H diff --git a/DSView/pv/view/xcursor.cpp b/DSView/pv/view/xcursor.cpp new file mode 100755 index 0000000000000000000000000000000000000000..24e4e30061ef7231d28cabc11025bfd6b46bd8ea --- /dev/null +++ b/DSView/pv/view/xcursor.cpp @@ -0,0 +1,233 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2012 Joel Holdsworth + * Copyright (C) 2013 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "xcursor.h" + +#include "view.h" +#include "ruler.h" +#include "../device/device.h" +#include "dsosignal.h" + +#include + +#include + +using namespace boost; +using namespace std; + +namespace pv { +namespace view { + +XCursor::XCursor(View &view, QColor &colour, + double value0, double value1) : + _view(view), + _yvalue(0.5), + _value0(value0), + _value1(value1), + _grabbed(XCur_None), + _colour(colour) +{ + _dsoSig = NULL; + const std::vector< boost::shared_ptr > sigs(_view.session().get_signals()); + BOOST_FOREACH(const boost::shared_ptr s, sigs) { + boost::shared_ptr dsoSig; + if (dsoSig = dynamic_pointer_cast(s)) + if (dsoSig->enabled()) { + _dsoSig = dsoSig; + break; + } + } +} + +XCursor::XCursor(const XCursor &x) : + QObject(), + _view(x._view), + _dsoSig(x._dsoSig), + _yvalue(x._yvalue), + _value0(x._value0), + _value1(x._value1), + _grabbed(XCur_None), + _colour(x._colour) +{ +} + +QColor XCursor::colour() const +{ + return _colour; +} + +void XCursor::set_colour(QColor color) +{ + _colour = color; +} + +/** + * Gets/Sets the mapping channel of the marker + */ +boost::shared_ptr XCursor::channel() const +{ + return _dsoSig; +} +void XCursor::set_channel(boost::shared_ptr sig) +{ + _dsoSig = sig; +} + +enum XCursor::XCur_type XCursor::grabbed() const +{ + return _grabbed; +} +void XCursor::set_grabbed(XCur_type type, bool grabbed) +{ + if (_grabbed == XCur_None && grabbed) + _grabbed = type; + else if (_grabbed == type && !grabbed) + _grabbed = XCur_None; +} +void XCursor::rel_grabbed() +{ + _grabbed = XCur_None; +} + +double XCursor::value(XCur_type type) const +{ + if (type == XCur_Y) + return _yvalue; + el