commit 9e51c5bb15149f2bebb603334842ecbacfbe8a1a Author: 谢炜 Date: Thu Jun 2 16:27:45 2022 +0800 Import Upstream version 3.14.0.0+0512 diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 00000000..a8b57e7b --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +shine diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/README.md b/README.md new file mode 100644 index 00000000..9b77fa00 --- /dev/null +++ b/README.md @@ -0,0 +1,189 @@ +## kylin-nm介绍 +### 简介 + 麒麟网络工具(kylin-network-manager,简称kylin-nm)是操作系统的网络前端,其主要功能有: + 1、托盘栏图标及右键菜单 + 查看当前网络状态 + 左键点击托盘网络图标显示kylin-nm主界面 + 右键点击托盘网络图标显示右键菜单 + 2、对有线网络的管理 + 有线网络界面管理 + 连接/断开网络 + 网线拔插 + 多有线网卡支持 + 打开或关闭有线开关 + 查看或修改无线网络基本信息 + 3、对无线网络的管理 + 切换及刷新无线界面 + 查看无线网络列表 + 连接/断开无需密码的无线网 + 连接/断开有密码类型的无线网 + 无线网卡插拔 + 多无线网卡支持 + 打开或关闭无线开关 + 查看或修改无线网络基本信息 + 4、连接隐藏无线网络 + 连接无安全性的无线网络 + 连接WPA及WPA2个人安全性的无线网络 + 连接WPA及WPA2企业安全性的无线网络 + 连接WPA3个人安全性的无线网络 + 5、窗口样式调节 + 深色与浅色窗口样式切换 + 调节网络工具窗口透明度 + 普通窗口与具有毛玻璃效果的窗口的切换 +### 运行 + 麒麟网络工具的进程为kylin-nm,默认开机自启,依赖NetworkManger +### 命令行和dbus接口 + + kylin-nm进程的命令行如下: + Usage: kylin-nm + +#### dbus接口: + DBUS类型:SESSION BUS + DBUS名称:com.kylin.network + OBJECT路径:/ + 接口名称:com.kylin.network + +#### dbus方法 + getWirelessList + 参数:无 + 返回值:QMap> + 键:网卡名称 + 值:无线网络的集合(第一项为已连接网络信息,若无连接则为"--",否则为"名称/信号强度/加密类型/Uuid/是否为本机开放热点";其余为未连接的网络信息,为"名称/信号强度/加密类型/是否为本机开放热点" + 功能:获取无线列表及每个对应无线网络的信号强度、加密类型等信息。 + + getWiredList + 参数:无 + 返回值:QMap> + 键:网卡名称 + 值:有线网络的集合("名称/UUID/对应DBUS路径"),若无已连接网络则第一项默认为"--" + 功能:获取有线列表及每个对应的有线网络的uuid及dbus路径 + + setWiredSwitchEnable(bool enable) + 参数:(bool)开启有线总开关(true)关闭有线总开关(false) + 返回值:无 + 功能:打开或关闭有线总开关 + + setWirelessSwitchEnable(bool enable) + 参数:(bool)开启无线总开关(true)关闭无线总开关(false) + 返回值:无 + 功能:打开或关闭无线总开关 + + setDeviceEnable(QString devName, bool enable) + 参数:(QString)devName 设备名称,(bool) enable 开启/关闭 + 返回值:无 + 功能:打开或关闭单个有线网卡开关 + + activateConnect(int type, QString devName, QString ssid) + 参数:根据网卡类型 参数1 0:lan 1:wlan 参数2:网卡名称 参数3:uuid/ssid + 返回值:无 + 功能:激活一个网络连接 + + deActivateConnect(int type, QString devName, QString ssid) + 参数:根据网卡类型 参数1 0:lan 1:wlan 参数2:网卡名称 参数3:uuid/ssid + 返回值:无 + 功能:断开一个网络连接 + + getDeviceListAndEnabled(int devType) + 参数:int devType 0:lan 1:wlan + 返回值:QMap + 键:设备名称 + 值:bool 开启(true)关闭 (false) + 功能:获取设备列表和启用/禁用状态 + + getWirelessDeviceCap + 返回值:QMap + 键:设备名称 + 值:int 0:不支持热点 3:支持2.4GHz 7:支持5GHz&&2.4Ghz + 功能:获取无线设备能力(2.4G/5G) + + showPropertyWidget(QString devName, QString ssid) + 参数:QString devName 设备名称 QString ssid 根据网卡类型 有线为uuid/无线为ssid + 返回值:无 + 功能:唤起对应网络连接的属性页,可以对基础信息的显示或修改 + + showCreateWiredConnectWidget(QString devName) + 参数:QString devName 有线网卡名称 + 返回值:无 + 功能:唤起新建有线连接界面 + + activeWirelessAp(const QString apName, + const QString apPassword, + const QString band, + const QString apDevice) + 参数:QString apName 热点名称 + QString apPassword 热点密码 + QString band 频带 + QString apDevice + 返回值:无 + 功能:开启移动热点 + + deactiveWirelessAp(const QString apName, const QString uuid) + 参数:QStringList(名称/密码/设备名称/状态/UUID/频带) + 返回值:无 + 功能: 断开移动热点 + + getStoredApInfo + 参数:QStringList(名称/密码/设备名称/状态/UUID/频带) + 返回值:无 + 功能:获取已保存的移动热点信息 + + getApInfoBySsid(QString devName, QString ssid) + 参数:QString devName 设备名称 QString ssid + 返回值:无 + 功能:通过名称获取已保存的移动热点信息 + + reScan() + 参数:无 + 返回值:无 + 功能:申请重新进行无线扫描 + + keyRingInit() + 参数:QString apName 热点名称 QString uuid + 返回值:无 + 功能:断开移动热点 + + keyRingClear() + 参数:无 + 返回值:无 + 功能: 断开移动热点 + + +### 原理与主要使用的技术 + kylin-nm主要与NetworkManager进行交互,通过对应的dbus信号驱动UI界面的更新。并通过提供的dbus方法来进行网络相关功能的调用。 + + 麒麟网络工具按照功能划分成两层:UI层和逻辑层。UI层实现网络资源的显示,以及用户的交互,逻辑层通过NetworkManager提供的Dbus接口,完成网络资源的管理及其配置。 +### 配置文件 + kylin-nm的配置文件保存在如下路径: + ~/.config/ukui/kylin-nm.conf 有线无线开关状态 设备状态 + org.ukui.kylin-nm.switch 对应的gsetting值 (有线无线开关状态) +### 编译 + cd kylin-nm + mkdir build + cd build + qmake .. + make + sudo make install  +### 运行命令 + ./kylin-nm +### 调试 + kylin-nm目前并采用ukui-log4qt模块的日志功能。日志默认保存在~/.log/kylin-nm.log中 + + + + + + + + + + + + + + + + + + + + diff --git a/kylin-nm.pro b/kylin-nm.pro new file mode 100644 index 00000000..4999ff17 --- /dev/null +++ b/kylin-nm.pro @@ -0,0 +1,13 @@ +TEMPLATE = subdirs + +CONFIG += ordered \ + qt + +SUBDIRS = \ + plugins/plugin.pro \ + src \ + +TRANSLATIONS += \ + translations/kylin-nm_zh_CN.ts \ + translations/kylin-nm_tr.ts \ + translations/kylin-nm_bo.ts diff --git a/man/kylin-nm.1 b/man/kylin-nm.1 new file mode 100644 index 00000000..846cd7eb --- /dev/null +++ b/man/kylin-nm.1 @@ -0,0 +1,20 @@ +.\" Man page for Kylin-nm +.TH KYLIN-NM 1 "20 September 2019" "UKUI Desktop Environment" +.\" Please adjust this date when revising the manpage. +.\" +.SH "NAME" +kylin-nm \- The tool for the UKUI Desktop Environment +.SH "SYNOPSIS" +.B kylin-nm +.SH "DESCRIPTION" +The \fBkylin-nm\fR program is a part of the ukui-indicators, It provides network manager for the the UKUI Desktop Environment. Detect the system disk automatically, Can pop up and open the device. +.PP +This manual page documents the \fBkylin-nm\fR command. +.P +.SH "BUGS" +.SS Should you encounter any bugs, they may be reported at: +https://github.com/ukui/kylin-nm/issues +.SH "AUTHORS" +.SS This Man Page has been written for the UKUI Desktop Environment by: +shine (2019) +.SH "SEE ALSO" \ No newline at end of file diff --git a/nmqrc.qrc b/nmqrc.qrc new file mode 100644 index 00000000..db90969b --- /dev/null +++ b/nmqrc.qrc @@ -0,0 +1,132 @@ + + + res/g/down_arrow.png + res/s/rescan/1.png + res/s/rescan/2.png + res/s/rescan/3.png + res/s/rescan/4.png + res/s/rescan/5.png + res/s/rescan/6.png + res/s/rescan/7.png + res/s/rescan/8.png + res/s/rescan/9.png + res/s/rescan/10.png + res/s/rescan/11.png + res/s/rescan/12.png + res/h/hide-pwd.png + res/h/right-pwd.png + res/h/show-pwd.png + res/h/no-pwd-wifi.png + translations/kylin-nm_bo.qm + translations/kylin-nm_tr.qm + translations/kylin-nm_zh_CN.qm + res/x/fly-mode-off.svg + res/x/fly-mode-on.svg + res/x/hot-spot-off.svg + res/x/hot-spot-on.svg + res/x/net-list-bg.svg + res/x/wifi-list-bg.svg + res/x/load-down.png + res/x/load-up.png + res/l/network-offline.png + res/l/network-offline.svg + res/l/network-online.png + res/l/network-online.svg + res/w/wifi-full.png + res/w/wifi-full-pwd.png + res/w/wifi-high.png + res/w/wifi-high-pwd.png + res/w/wifi-low.png + res/w/wifi-low-pwd.png + res/w/wifi-medium.png + res/w/wifi-medium-pwd.png + res/w/wifi-none.png + res/w/wifi-none-pwd.png + res/s/conning-a/1.png + res/s/conning-a/2.png + res/s/conning-a/3.png + res/s/conning-a/4.png + res/s/conning-a/5.png + res/s/conning-a/6.png + res/s/conning-a/7.png + res/s/conning-a/8.png + res/g/close_black.png + res/g/close_white.png + res/s/conning-s/1.png + res/s/conning-s/2.png + res/s/conning-s/3.png + res/s/conning-s/4.png + res/s/conning-s/5.png + res/s/conning-s/6.png + res/s/conning-s/7.png + res/s/conning-s/8.png + res/s/conning-s/9.png + res/s/conning-s/10.png + res/s/conning-s/11.png + res/s/conning-s/12.png + res/x/setup.png + res/x/control.svg + res/w/wifi6-full-pwd.png + res/w/wifi6-full.png + res/w/wifi6-high-pwd.png + res/w/wifi6-high.png + res/w/wifi6-low-pwd.png + res/w/wifi6-low.png + res/w/wifi6-medium-pwd.png + res/w/wifi6-medium.png + res/w/wifi6-none.png + res/w/wifi6+-none.png + res/w/wifi6+-meidum-pwd.png + res/w/wifi6+-medium.png + res/w/wifi6+-medium-pwd.png + res/w/wifi6+-low.png + res/w/wifi6+-low-pwd.png + res/w/wifi6+-high.png + res/w/wifi6+-high-pwd.png + res/w/wifi6+-full.png + res/w/wifi6+-full-pwd.png + res/w/wifi6-none-pwd.png + res/hw/wifi-full-pwd.png + res/hw/wifi-full.png + res/hw/wifi-high-pwd.png + res/hw/wifi-high.png + res/hw/wifi-low-pwd.png + res/hw/wifi-low.png + res/hw/wifi-medium-pwd.png + res/hw/wifi-medium.png + res/hw/wifi-none-pwd.png + res/hw/wifi-none.png + res/hw/wifi6-full-pwd.png + res/hw/wifi6-full.png + res/hw/wifi6-high-pwd.png + res/hw/wifi6-high.png + res/hw/wifi6-low-pwd.png + res/hw/wifi6-low.png + res/hw/wifi6-medium-pwd.png + res/hw/wifi6-medium.png + res/hw/wifi6-none-pwd.png + res/hw/wifi6-none.png + res/hw/wifi6+-full-pwd.png + res/hw/wifi6+-full.png + res/hw/wifi6+-high-pwd.png + res/hw/wifi6+-high.png + res/hw/wifi6+-low-pwd.png + res/hw/wifi6+-low.png + res/hw/wifi6+-medium-pwd.png + res/hw/wifi6+-medium.png + res/hw/wifi6+-none-pwd.png + res/hw/wifi6+-none.png + res/s/conning-b/1.png + res/s/conning-b/2.png + res/s/conning-b/3.png + res/s/conning-b/4.png + res/s/conning-b/5.png + res/s/conning-b/6.png + res/s/conning-b/7.png + res/s/conning-b/8.png + res/s/conning-b/9.png + res/s/conning-b/10.png + res/s/conning-b/11.png + res/s/conning-b/12.png + + diff --git a/plugins/component/DrownLabel/drownlabel.cpp b/plugins/component/DrownLabel/drownlabel.cpp new file mode 100644 index 00000000..4e46523a --- /dev/null +++ b/plugins/component/DrownLabel/drownlabel.cpp @@ -0,0 +1,36 @@ +#include "drownlabel.h" +#include "deviceframe.h" + +#define ICONSIZE 16,16 +DrownLabel::DrownLabel(QString devName, QWidget * parent) : QLabel(parent) +{ + m_devName = devName; + setFixedSize(36,36); + loadPixmap(isChecked); + this->setProperty("useIconHighlightEffect", 0x2); +} + +DrownLabel::~DrownLabel() +{ + +} +void DrownLabel::setDropDownStatus(bool status) +{ + isChecked = status; + loadPixmap(isChecked); +} + +void DrownLabel::loadPixmap(bool isChecked) +{ + if (isChecked) { + setPixmap(QIcon::fromTheme("ukui-up-symbolic").pixmap(ICONSIZE)); + } else { + setPixmap(QIcon::fromTheme("ukui-down-symbolic").pixmap(ICONSIZE)); + } +} + +void DrownLabel::mouseReleaseEvent(QMouseEvent *event) +{ + emit labelClicked(); + QWidget::mouseReleaseEvent(event); +} diff --git a/plugins/component/DrownLabel/drownlabel.h b/plugins/component/DrownLabel/drownlabel.h new file mode 100644 index 00000000..806dc132 --- /dev/null +++ b/plugins/component/DrownLabel/drownlabel.h @@ -0,0 +1,27 @@ +#ifndef DROWNLABEL_H +#define DROWNLABEL_H + +#include +#include +#include +#include + +class DrownLabel : public QLabel +{ + Q_OBJECT +public: + explicit DrownLabel(QString devName, QWidget * parent = nullptr); + ~DrownLabel(); + void setDropDownStatus(bool status); + QString m_devName; + bool isChecked = true; +private: + void loadPixmap(bool isChecked); +protected: + virtual void mouseReleaseEvent(QMouseEvent * event); + +Q_SIGNALS: + void labelClicked(); +}; + +#endif // DROWNLABEL_H diff --git a/plugins/component/InfoButton/infobutton.cpp b/plugins/component/InfoButton/infobutton.cpp new file mode 100644 index 00000000..e434c0fb --- /dev/null +++ b/plugins/component/InfoButton/infobutton.cpp @@ -0,0 +1,105 @@ +#include "infobutton.h" +#include +#include +#include +#include + +#define BUTTON_SIZE 36,36 +#define ICON_SIZE 16,16 +#define BACKGROUND_COLOR QColor(0,0,0,0) +#define FOREGROUND_COLOR_NORMAL qApp->palette().text().color() +#define FOREGROUND_COLOR_HOVER QColor(55,144,250,255) +#define FOREGROUND_COLOR_PRESS QColor(36,109,212,255) +#define OUTER_PATH 8,8,16,16 +#define INNER_PATH 9,9,14,14 +#define TEXT_POS 14,5,16,16,0 + +#define BUTTON_SIZE 36,36 + +#define THEME_SCHAME "org.ukui.style" +#define COLOR_THEME "styleName" + +InfoButton::InfoButton(QWidget *parent) : QPushButton(parent) +{ + this->setFixedSize(BUTTON_SIZE); + initUI(); + const QByteArray style_id(THEME_SCHAME); + if (QGSettings::isSchemaInstalled(style_id)) { + m_styleGsettings = new QGSettings(style_id); + connect(m_styleGsettings, &QGSettings::changed, this, &InfoButton::onGSettingChaned); + } else { + qDebug() << "Gsettings interface \"org.ukui.style\" is not exist!"; + } +} + +void InfoButton::initUI() +{ + this->setFixedSize(BUTTON_SIZE); + m_backgroundColor = BACKGROUND_COLOR; + m_foregroundColor = FOREGROUND_COLOR_NORMAL; +} + +void InfoButton::onGSettingChaned(const QString &key) +{ + if (key == COLOR_THEME) { + m_foregroundColor = FOREGROUND_COLOR_NORMAL; + this->repaint(); + } +} + +void InfoButton::paintEvent(QPaintEvent *event) +{ + QPalette pal = this->palette(); + pal.setColor(QPalette::Base, m_backgroundColor); + pal.setColor(QPalette::Text, m_foregroundColor); + + QPainterPath cPath; + cPath.addRect(0, 0, ICON_SIZE); + cPath.addEllipse(0, 0, ICON_SIZE); + + QPainterPath outerPath; + outerPath.addEllipse(OUTER_PATH); + + QPainterPath innerPath; + innerPath.addEllipse(INNER_PATH); + outerPath -= innerPath; + + QPainter painter(this); + painter.setRenderHint(QPainter:: Antialiasing, true); //设置渲染,启动反锯齿 + painter.setPen(Qt::NoPen); + + painter.setBrush(pal.color(QPalette::Base)); + painter.drawPath(cPath); + + painter.fillPath(outerPath, pal.color(QPalette::Text)); + painter.setPen(m_foregroundColor); + QFont font("Noto Sans CJK SC", 11, QFont::Normal, false); + painter.setFont(font); + painter.drawText(TEXT_POS, "i"); +} + +void InfoButton::enterEvent(QEvent *event) +{ + m_foregroundColor = FOREGROUND_COLOR_HOVER; + this->repaint(); +} + +void InfoButton::leaveEvent(QEvent *event) +{ + m_foregroundColor = FOREGROUND_COLOR_NORMAL; + this->repaint(); +} + +void InfoButton::mousePressEvent(QMouseEvent *event) +{ + m_foregroundColor = FOREGROUND_COLOR_PRESS; + this->repaint(); + return QPushButton::mousePressEvent(event); +} + +void InfoButton::mouseReleaseEvent(QMouseEvent *event) +{ + m_foregroundColor = FOREGROUND_COLOR_HOVER; + this->repaint(); + return QPushButton::mouseReleaseEvent(event); +} diff --git a/plugins/component/InfoButton/infobutton.h b/plugins/component/InfoButton/infobutton.h new file mode 100644 index 00000000..6376b028 --- /dev/null +++ b/plugins/component/InfoButton/infobutton.h @@ -0,0 +1,35 @@ +#ifndef INFOBUTTON_H +#define INFOBUTTON_H +#include +#include +#include + +class InfoButton : public QPushButton +{ + Q_OBJECT +public: + explicit InfoButton(QWidget * parent = nullptr); + ~InfoButton() = default; + +protected: + void paintEvent(QPaintEvent *event); + void enterEvent(QEvent *event); + void leaveEvent(QEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + +private: + void initUI(); + +private: + QColor m_backgroundColor; + QColor m_foregroundColor; + + //监听主题的Gsettings + QGSettings * m_styleGsettings = nullptr; + +private slots: + void onGSettingChaned(const QString &key); +}; + +#endif // INFOBUTTON_H diff --git a/plugins/component/SwitchButton/switchbutton.cpp b/plugins/component/SwitchButton/switchbutton.cpp new file mode 100644 index 00000000..a7e62f65 --- /dev/null +++ b/plugins/component/SwitchButton/switchbutton.cpp @@ -0,0 +1,327 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. + * + * 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 "switchbutton.h" + +#include +#define THEME_QT_SCHEMA "org.ukui.style" +#define THEME_GTK_SCHEMA "org.mate.interface" +#define TIMER_INTERVAL 5 //每隔5ms动画移动一次 +#define MOVING_STEPS 40 //动画总共移动40次 + +SwitchButton::SwitchButton(QWidget *parent, bool useDisableStyle) : + QWidget(parent) +{ +// this->resize(QSize(52, 24)); + this->setFixedSize(QSize(50, 24)); + + checked = false; + hover = false; + disabled = false; + isMoving = false; + isAnimation = true; + m_useDisableStyle = useDisableStyle; + + space = 4; + rectRadius = height()/2; + + mStep = width()/MOVING_STEPS;//也就是40次动画就可以走完,每次时间间隔是固定的5ms + mStartX = 0; + mEndX= 0; + + mTimer = new QTimer(this); + mTimer->setInterval(TIMER_INTERVAL);//动画更新时间 + connect(mTimer, SIGNAL(timeout()), this, SLOT(updatevalue())); + if(QGSettings::isSchemaInstalled(THEME_GTK_SCHEMA) && QGSettings::isSchemaInstalled(THEME_QT_SCHEMA)) { + QByteArray qtThemeID(THEME_QT_SCHEMA); + QByteArray gtkThemeID(THEME_GTK_SCHEMA); + + m_gtkThemeSetting = new QGSettings(gtkThemeID,QByteArray(),this); + m_qtThemeSetting = new QGSettings(qtThemeID,QByteArray(),this); + + QString style = m_qtThemeSetting->get("styleName").toString(); + changeColor(style); + + connect(m_qtThemeSetting,&QGSettings::changed, [this] (const QString &key) { + QString style = m_qtThemeSetting->get("styleName").toString(); + if (key == "styleName") { + changeColor(style); + } + }); + } +} + +SwitchButton::~SwitchButton() +{ +} + +void SwitchButton::paintEvent(QPaintEvent *){ + + QPainter painter(this); + //启用反锯齿 + painter.setRenderHint(QPainter::Antialiasing, true); + painter.setCompositionMode(QPainter::CompositionMode_Source); + drawBg(&painter); + if(!isAnimation)//动画如果禁用,则圆形滑块isMoving始终为false + isMoving =false; + if(isMoving) + animation(&painter); + drawSlider(&painter); + painter.end(); +} + +void SwitchButton::changeColor(const QString &themes) { + if (hover) { + return ;//在鼠标下,禁止切换颜色鼠标离开时切换颜色 + } + if (themes == "ukui-dark" || themes == "ukui-black") { + bgColorOff = QColor(OFF_BG_DARK_COLOR); + bgColorOn = QColor(ON_BG_DARK_COLOR); + rectColorEnabled = QColor(ENABLE_RECT_DARK_COLOR); + rectColorDisabled = QColor(DISABLE_RECT_DARK_COLOR); + sliderColorDisabled = QColor(DISABLE_RECT_DARK_COLOR); + sliderColorEnabled = QColor(ENABLE_RECT_DARK_COLOR); + bgHoverOnColor = QColor(ON_HOVER_BG_DARK_COLOR); + bgHoverOffColor = QColor(OFF_HOVER_BG_DARK_COLOR); + bgColorDisabled = QColor(DISABLE_DARK_COLOR); + } else { + bgColorOff = QColor(OFF_BG_LIGHT_COLOR); + bgColorOn = QColor(ON_BG_LIGHT_COLOR); + rectColorEnabled = QColor(ENABLE_RECT_LIGHT_COLOR); + rectColorDisabled = QColor(DISABLE_RECT_LIGHT_COLOR); + sliderColorDisabled = QColor(DISABLE_RECT_LIGHT_COLOR); + sliderColorEnabled = QColor(ENABLE_RECT_LIGHT_COLOR); + bgHoverOnColor = QColor(ON_HOVER_BG_LIGHT_COLOR); + bgHoverOffColor = QColor(OFF_HOVER_BG_LIGHT_COLOR); + bgColorDisabled = QColor(DISABLE_LIGHT_COLOR); + } +} + +//动画绘制 +void SwitchButton::animation(QPainter *painter){ + painter->save(); + int h = height(); + int w = width(); + painter->setPen(Qt::NoPen); + //颜色设置 + if(checked){ + //开关在左侧时 + painter->setBrush(bgColorOn); + rect.setRect(0,0,h+mStartX,h); + }else{ + painter->setBrush(bgColorOff); + rect.setRect(mStartX,0,w-mStartX,h); + } + painter->drawRoundedRect(rect,rectRadius,rectRadius); + + painter->restore(); +} + +//绘制背景 +void SwitchButton::drawBg(QPainter *painter){ + int w = width(); + int h = height(); + painter->save(); + painter->setPen(Qt::NoPen); + if (disabled && m_useDisableStyle) { + painter->setPen(Qt::NoPen); + painter->setBrush(bgColorDisabled); + } else { + if(checked){ + if(isMoving){ + painter->setBrush(bgColorOff); + rect.setRect(mStartX,0,w-mStartX,h); + }else { + painter->setBrush(bgColorOn); + rect.setRect(0, 0, w, h); + } + }else{ + if(isMoving){ + painter->setBrush(bgColorOn); + rect.setRect(0,0,mStartX+h,h); + } + else { + painter->setBrush(bgColorOff); + rect.setRect(0, 0, w, h); + } + } + } + //半径为高度的一半 + painter->drawRoundedRect(rect,rectRadius,rectRadius); + + painter->restore(); +} + +//绘制滑块,也就是圆形按钮 +void SwitchButton::drawSlider(QPainter *painter){ + painter->save(); + painter->setPen(Qt::NoPen); + + if (!disabled || !m_useDisableStyle){ + painter->setBrush(sliderColorEnabled); + } + else + painter->setBrush(sliderColorDisabled); + if (disabled) { + if (!checked){ + QRect smallRect(8, height() / 2 - 2, 10 , 4); + painter->drawRoundedRect(smallRect,3,3); + }else{ + QRect smallRect(width() - 8 * 2, height() / 2 - 2, 10 , 4); + painter->drawRoundedRect(smallRect,3,3); + } + } + + QRect rect(0, 0, width(), height()); + int sliderWidth = rect.height() - space * 2; + QRect sliderRect(mStartX + space, space, sliderWidth, sliderWidth); + painter->drawEllipse(sliderRect); + + painter->restore(); +} + +void SwitchButton::mousePressEvent(QMouseEvent *){ + qDebug()<start(); + isMoving = true; + } +} + +void SwitchButton::resizeEvent(QResizeEvent *){ + //每次开始的x坐标都是跳过圆角,从直线的地方开始计算 + mStep = width() / MOVING_STEPS; + + if (checked){ + //circle out +// startX = width() - height() + space; + //circle in + mStartX = width() - height(); + } + else + mStartX = 0; + + rectRadius = height()/2; + update(); +} +void SwitchButton::enterEvent(QEvent *event) { + bgColorOn = bgHoverOnColor; + bgColorOff = bgHoverOffColor; + + hover = true; + update(); + return QWidget::enterEvent(event); +} + +void SwitchButton::leaveEvent(QEvent *event) { + hover = false; + + QString style = m_qtThemeSetting->get("styleName").toString(); + changeColor(style); + + update(); + return QWidget::leaveEvent(event); +} + +//根据事件向左还是向右移动 +void SwitchButton::updatevalue(){ + if (checked) + if (mStartX < mEndX-mStep){ + mStartX = mStartX + mStep; + } + else{ + mStartX = mEndX; + mTimer->stop(); + isMoving = false; + } + else{ + if (mStartX > mEndX+mStep){ + mStartX = mStartX - mStep; + } + else{ + mStartX = mEndX; + mTimer->stop(); + isMoving = false; + } + } + update(); +} + +void SwitchButton::setChecked(bool checked){ + if (this->checked != checked){ + this->checked = checked; + Q_EMIT checkedChanged(checked); + update(); + } + + mStep = width() / MOVING_STEPS; + + if (checked){ + //circle out +// endX = width() - height() + space; + //circle in + mEndX = width() - height(); + } + else{ + mEndX = 0; + } + mTimer->start(); + isMoving = true; +} + +bool SwitchButton::isChecked(){ + return this->checked; +} + +void SwitchButton::setDisabledFlag(bool value) +{ + disabled = value; + update(); +} + +bool SwitchButton::getDisabledFlag() +{ + return disabled; +} + +void SwitchButton::setAnimation(bool on){ + isAnimation = on; +} + diff --git a/plugins/component/SwitchButton/switchbutton.h b/plugins/component/SwitchButton/switchbutton.h new file mode 100644 index 00000000..a54e501b --- /dev/null +++ b/plugins/component/SwitchButton/switchbutton.h @@ -0,0 +1,121 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. + * + * 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 SWITCHBUTTON_H +#define SWITCHBUTTON_H + +#include +#include +#include +#include +#include +#include + +#define OFF_BG_DARK_COLOR "#404040" +#define OFF_HOVER_BG_DARK_COLOR "#666666" +#define ON_BG_DARK_COLOR "#3790FA" +#define ON_HOVER_BG_DARK_COLOR "#40A9FB" +#define DISABLE_DARK_COLOR "#474747" +#define DISABLE_RECT_DARK_COLOR "#6E6E6E" +#define ENABLE_RECT_DARK_COLOR "#FFFFFF" + +#define OFF_BG_LIGHT_COLOR "#E0E0E0" +#define OFF_HOVER_BG_LIGHT_COLOR "#B3B3B3" +#define ON_BG_LIGHT_COLOR "#3790FA" +#define ON_HOVER_BG_LIGHT_COLOR "#40A9FB" +#define DISABLE_LIGHT_COLOR "#E9E9E9" +#define DISABLE_RECT_LIGHT_COLOR "#B3B3B3" +#define ENABLE_RECT_LIGHT_COLOR "#FFFFFF" + + +class SwitchButton : public QWidget +{ + Q_OBJECT + +public: + SwitchButton(QWidget *parent = 0, bool useDisableStyle = true); + ~SwitchButton(); + + void setChecked(bool checked); + void setAnimation(bool on); + + bool isChecked(); + void setDisabledFlag(bool); + bool getDisabledFlag(); +protected: + void mousePressEvent(QMouseEvent *); + void resizeEvent(QResizeEvent *); + void paintEvent(QPaintEvent *); + void enterEvent(QEvent *event); + void leaveEvent(QEvent *event); + + void drawBg(QPainter * painter); + void drawSlider(QPainter * painter); + void changeColor(const QString &themes); + +private: + bool checked; //切换的判断 + bool disabled; + + void animation(QPainter *painter); + QRect rect; + bool isMoving; //滑块动作判断 + bool isAnimation; // 是否允许动画执行 + + QColor bgColorOff; + QColor bgColorOn; + QColor bgHoverOnColor; + QColor bgHoverOffColor; + QColor bgColorDisabled; + + QColor sliderColorEnabled; + QColor sliderColorDisabled; + + + QColor rectColorEnabled; + QColor rectColorDisabled; + + QColor sliderColorOff; + QColor sliderColorOn; + QGSettings *m_qtThemeSetting; + QGSettings *m_gtkThemeSetting; + + int space; //滑块离背景间隔 + int rectRadius; //圆角角度 + + int mStep; //移动步长 + int mStartX; + int mEndX; + + bool hover; + QTimer * mTimer; + + bool m_useDisableStyle; + + +private Q_SLOTS: + void updatevalue(); + + +Q_SIGNALS: + void checkedChanged(bool checked); + void disabledClick(); +}; + +#endif // SWITCHBUTTON_H diff --git a/plugins/component/drownlabel.pri b/plugins/component/drownlabel.pri new file mode 100644 index 00000000..185bbd36 --- /dev/null +++ b/plugins/component/drownlabel.pri @@ -0,0 +1,9 @@ +#LIBINTERFACE_NAME = $$qtLibraryTarget(drownlabel) + +SOURCES += \ + $$PWD/DrownLabel/drownlabel.cpp \ + +HEADERS += \ + $$PWD/DrownLabel/drownlabel.h \ + + diff --git a/plugins/component/infobutton.pri b/plugins/component/infobutton.pri new file mode 100644 index 00000000..5e84a760 --- /dev/null +++ b/plugins/component/infobutton.pri @@ -0,0 +1,9 @@ +#LIBINTERFACE_NAME = $$qtLibraryTarget(infobutton) + +SOURCES += \ + $$PWD/InfoButton/infobutton.cpp \ + +HEADERS += \ + $$PWD/InfoButton/infobutton.h \ + + diff --git a/plugins/component/switchbutton.pri b/plugins/component/switchbutton.pri new file mode 100644 index 00000000..b1c4b1bc --- /dev/null +++ b/plugins/component/switchbutton.pri @@ -0,0 +1,8 @@ + +#LIBINTERFACE_NAME = $$qtLibraryTarget(switchbutton) + +SOURCES += \ + $$PWD/SwitchButton/switchbutton.cpp \ + +HEADERS += \ + $$PWD/SwitchButton/switchbutton.h \ diff --git a/plugins/mobilehotspot/mobilehotspot.cpp b/plugins/mobilehotspot/mobilehotspot.cpp new file mode 100644 index 00000000..2a456228 --- /dev/null +++ b/plugins/mobilehotspot/mobilehotspot.cpp @@ -0,0 +1,155 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. + * + * 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 "mobilehotspot.h" + + +#include + + +MobileHotspot::MobileHotspot() : mFirstLoad(true) { + + QTranslator* translator = new QTranslator(this); + qDebug() << "/usr/share/kylin-nm/mobilehotspot/" + QLocale::system().name(); + if (!translator->load("/usr/share/kylin-nm/mobilehotspot/" + QLocale::system().name())) { + qDebug() << "load failed"; + } + QApplication::installTranslator(translator); + + pluginName = tr("MobileHotspot"); + qDebug() << pluginName; + pluginType = NETWORK; + + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); + needLoad = isExitWirelessDevice(); +} + +MobileHotspot::~MobileHotspot() +{ + if (!mFirstLoad) { +// delete pluginWidget; +// pluginWidget = nullptr; + + } +} + +QString MobileHotspot::plugini18nName() { + return pluginName; +} + +int MobileHotspot::pluginTypes() { + return pluginType; +} + +QWidget *MobileHotspot::pluginUi() { + if (mFirstLoad) { + mFirstLoad = false; + + pluginWidget = new MobileHotspotWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + } + return pluginWidget; +} + +const QString MobileHotspot::name() const { + + return QStringLiteral("mobilehotspot"); +} + +bool MobileHotspot::isEnable() const +{ + qDebug() << needLoad; + return needLoad; +} + + +bool MobileHotspot::isShowOnHomePage() const +{ + return false; +} + +QIcon MobileHotspot::icon() const +{ + return QIcon(); +} + +QString MobileHotspot::translationPath() const +{ + return "/usr/share/kylin-nm/mobilehotspot/%1.ts"; +} + +void MobileHotspot::initSearchText() +{ + //~ contents_path /mobilehotspot/mobilehotspot + tr("mobilehotspot"); + //~ contents_path /mobilehotspot/mobilehotspot open + tr("mobilehotspot open"); +} + +bool MobileHotspot::isExitWirelessDevice() +{ + QDBusInterface *interface = new QDBusInterface("com.kylin.network", "/com/kylin/network", + "com.kylin.network", + QDBusConnection::sessionBus()); + if (!interface->isValid()) { + qDebug() << "/com/kylin/network is invalid"; + return false; + } + + QDBusMessage result = interface->call(QStringLiteral("getDeviceListAndEnabled"),1); + if(result.type() == QDBusMessage::ErrorMessage) { + qWarning() << "getWirelessDeviceList error:" << result.errorMessage(); + return false; + } + + auto dbusArg = result.arguments().at(0).value(); + QMap deviceListMap; + dbusArg >> deviceListMap; + + QDBusReply > capReply = interface->call("getWirelessDeviceCap"); + if (!capReply.isValid()) { + qDebug()<<"execute dbus method 'getWirelessDeviceCap' is invalid in func initInterfaceInfo()" < devCapMap = capReply.value(); + + + if (deviceListMap.isEmpty()) { + qDebug() << "no wireless device"; + return false; + } else { + QMap::Iterator iter = deviceListMap.begin(); + while (iter != deviceListMap.end()) { + QString interfaceName = iter.key(); + if (!devCapMap.contains(interfaceName)) { + iter++; + continue; + } + if (deviceListMap[interfaceName] & 0x01) { + qDebug() << "wireless device" << interfaceName << "support hotspot"; + return true; + } + iter++; + } + } + qDebug() << "no wireless device support hotspot"; + return false; +} + diff --git a/plugins/mobilehotspot/mobilehotspot.h b/plugins/mobilehotspot/mobilehotspot.h new file mode 100644 index 00000000..7bb3cb63 --- /dev/null +++ b/plugins/mobilehotspot/mobilehotspot.h @@ -0,0 +1,78 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. + * + * 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 MOBILEHOTSPOT_H +#define MOBILEHOTSPOT_H + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "interface.h" +#include "switchbutton.h" +#include "hoverbtn.h" +#include "mobilehotspotwidget.h" + + +namespace Ui { +class MobileHotspot; +} + +class MobileHotspot : public QObject, CommonInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.ukcc.CommonInterface") + Q_INTERFACES(CommonInterface) + +public: + MobileHotspot(); + ~MobileHotspot(); + + QString plugini18nName() Q_DECL_OVERRIDE; + int pluginTypes() Q_DECL_OVERRIDE; + QWidget * pluginUi() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; + bool isShowOnHomePage() const Q_DECL_OVERRIDE; + QIcon icon() const Q_DECL_OVERRIDE; + bool isEnable() const Q_DECL_OVERRIDE; + QString translationPath() const Q_DECL_OVERRIDE; + +private: + + void initSearchText(); + bool isExitWirelessDevice(); + + QString pluginName; + int pluginType; + MobileHotspotWidget *pluginWidget; + +private: + bool mFirstLoad; + bool needLoad; + +}; +#endif // MOBILEHOTSPOT_H diff --git a/plugins/mobilehotspot/mobilehotspot.pro b/plugins/mobilehotspot/mobilehotspot.pro new file mode 100644 index 00000000..a9fde8d3 --- /dev/null +++ b/plugins/mobilehotspot/mobilehotspot.pro @@ -0,0 +1,42 @@ +QT += widgets network dbus gui core +TEMPLATE = lib +CONFIG += plugin + +TARGET = $$qtLibraryTarget(mobilehotspot) +DESTDIR = ../.. +target.path = $$[QT_INSTALL_LIBS]/ukui-control-center +trans.files = translations/* +trans.path = /usr/share/kylin-nm/mobilehotspot/ + +INCLUDEPATH += \ + $$PROJECT_COMPONENTSOURCE \ + $$PROJECT_ROOTDIR \ + /usr/include/ukcc/interface \ + /usr/include/ukcc/widgets + +LIBS += -L$$[QT_INSTALL_LIBS] -lgsettings-qt -lukcc + +CONFIG += c++11 \ + link_pkgconfig \ + +PKGCONFIG += gsettings-qt \ + +#DEFINES += QT_DEPRECATED_WARNINGS + +SOURCES += \ + mobilehotspot.cpp \ + mobilehotspotwidget.cpp + +HEADERS += \ + mobilehotspot.h \ + mobilehotspotwidget.h \ + libukcc_global.h + + +INSTALLS += target \ + trans + +TRANSLATIONS += \ + translations/zh_CN.ts \ + translations/tr.ts \ + translations/bo.ts diff --git a/plugins/mobilehotspot/mobilehotspotwidget.cpp b/plugins/mobilehotspot/mobilehotspotwidget.cpp new file mode 100644 index 00000000..9d4abdd4 --- /dev/null +++ b/plugins/mobilehotspot/mobilehotspotwidget.cpp @@ -0,0 +1,678 @@ +#include "mobilehotspotwidget.h" +#include + +#define LABEL_RECT 17, 0, 105, 23 +#define CONTENTS_MARGINS 0, 0, 0, 0 +#define FRAME_MIN_SIZE 550, 60 +#define FRAME_MAX_SIZE 16777215, 16777215 +#define CONTECT_FRAME_MAX_SIZE 16777215, 60 +#define LABLE_MIN_WIDTH 140 +#define COMBOBOX_MIN_WIDTH 200 +#define LINE_MAX_SIZE 16777215, 1 +#define LINE_MIN_SIZE 0, 1 +#define LAYOUT_LEFT_MARGINS 8 +#define ICON_SIZE 24,24 + +#define WIRELESS 1 + +#define AP_NAME_MAX_LENGTH 32 + +const QByteArray GSETTINGS_SCHEMA = "org.ukui.kylin-nm.switch"; +const QString WIRELESS_SWITCH = "wirelessswitch"; + +void MobileHotspotWidget::showDesktopNotify(const QString &message) +{ + QDBusInterface iface("org.freedesktop.Notifications", + "/org/freedesktop/Notifications", + "org.freedesktop.Notifications", + QDBusConnection::sessionBus()); + QList args; + args<<(tr("ukui control center")) + <<((unsigned int) 0) + <setContentsMargins(CONTENTS_MARGINS); + + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >>(); + + initUI(); + m_switchBtn->installEventFilter(this); + m_interface = new QDBusInterface("com.kylin.network", "/com/kylin/network", + "com.kylin.network", + QDBusConnection::sessionBus()); + if(!m_interface->isValid()) { + qDebug() << "dbus interface com.kylin.network is invaild"; + m_switchBtn->setChecked(false); + setUiEnabled(false); + } + + m_hostName = getHostName(); + + initDbusConnect(); + + initInterfaceInfo(); + getApInfo(); + + connect(m_switchBtn, &SwitchButton::checkedChanged, this, &MobileHotspotWidget::setUiEnabled); + connect(m_interfaceComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, [=]() { + m_interfaceName = m_interfaceComboBox->currentText(); + updateBandCombox(); + }); + connect(m_pwdShowBox, &QCheckBox::clicked, this, [=]() { + if (m_pwdNameLine->echoMode() == QLineEdit::Password) { + m_pwdShowBox->setIcon(QIcon::fromTheme("ukui-eye-display-symbolic")); + m_pwdNameLine->setEchoMode(QLineEdit::Normal); + } else { + m_pwdNameLine->setEchoMode(QLineEdit::Password); + m_pwdShowBox->setIcon(QIcon::fromTheme("ukui-eye-hidden-symbolic")); + } + }); +} + +MobileHotspotWidget::~MobileHotspotWidget() +{ + delete m_interface; +} + +bool MobileHotspotWidget::eventFilter(QObject *watched, QEvent *event) +{ + if (event->type() == QEvent::MouseButtonDblClick && watched == m_switchBtn) { + return true; + } + + if (event->type() == QEvent::MouseButtonPress) { + if (watched == m_switchBtn) { + if (!m_interface->isValid()) { + return true; + } + if (m_switchBtn->getDisabledFlag()) { + showDesktopNotify(tr("wirless switch is close or no wireless device")); + return true; + } + if (m_switchBtn->isChecked()) { + showDesktopNotify(tr("start to close hotspot")); + QDBusReply reply = m_interface->call("deactiveWirelessAp", m_apNameLine->text(), m_uuid); + if (!reply.isValid()) { + qDebug() << "[MobileHotspotWidget] call deactiveWirelessAp failed "; + return true; + } + } else { + if (m_apNameLine->text().isEmpty() || m_interfaceName.isEmpty()) + { + showDesktopNotify(tr("hotpots name or device is invalid")); + return true; + } + if (m_pwdNameLine->text().length() < 8) { + showDesktopNotify(tr("can not create hotspot with password length less than eight!")); + return true; + } + showDesktopNotify(tr("start to open hotspot ") + m_apNameLine->text()); + QDBusReply reply = m_interface->call("activeWirelessAp", + m_apNameLine->text(), + m_pwdNameLine->text(), + m_freqBandComboBox->currentText(), + m_interfaceComboBox->currentText()); + if (!reply.isValid()) { + qDebug() << "[MobileHotspotWidget] call deactiveWirelessAp failed "; + return true; + } + } + return true; + } + } + return QWidget::eventFilter(watched, event); +} + +void MobileHotspotWidget::paintEvent(QPaintEvent *event) +{ + QWidget::paintEvent(event); +} + +void MobileHotspotWidget::initUI() +{ + QFrame *hotspotFrame = new QFrame(this); + hotspotFrame->setMinimumSize(FRAME_MIN_SIZE); + hotspotFrame->setMaximumSize(FRAME_MAX_SIZE); + hotspotFrame->setFrameShape(QFrame::Box); + + QVBoxLayout *hotspotLyt = new QVBoxLayout(hotspotFrame); + hotspotLyt->setContentsMargins(0, 0, 0, 0); + + m_hotspotTitleLabel = new TitleLabel(this); + m_hotspotTitleLabel->setText(tr("Hotspot")); + + setSwitchFrame(); + setApNameFrame(); + setPasswordFrame(); + setFreqBandFrame(); + setInterFaceFrame(); + + switchAndApNameLine = myLine(); + apNameAndPwdLine = myLine(); + pwdAndfreqBandLine = myLine(); + freqBandAndInterfaceLine = myLine(); + + /* add widget */ + hotspotLyt->addWidget(m_switchFrame); + hotspotLyt->addWidget(switchAndApNameLine); + hotspotLyt->addWidget(m_ApNameFrame); + hotspotLyt->addWidget(apNameAndPwdLine); + hotspotLyt->addWidget(m_passwordFrame); + hotspotLyt->addWidget(pwdAndfreqBandLine); + hotspotLyt->addWidget(m_freqBandFrame); + hotspotLyt->addWidget(freqBandAndInterfaceLine); + hotspotLyt->addWidget(m_interfaceFrame); + hotspotLyt->setSpacing(0); + + mVlayout->addWidget(m_hotspotTitleLabel); + mVlayout->setSpacing(8); + mVlayout->addWidget(hotspotFrame); + mVlayout->addStretch(); +} + +void MobileHotspotWidget::initDbusConnect() +{ + if(m_interface->isValid()) { + connect(m_interface,SIGNAL(activateFailed(QString)), this, SLOT(onActivateFailed(QString)), Qt::QueuedConnection); + connect(m_interface,SIGNAL(deactivateFailed(QString)), this, SLOT(onDeactivateFailed(QString)), Qt::QueuedConnection); + connect(m_interface,SIGNAL(deviceStatusChanged()), this, SLOT(onDeviceStatusChanged()), Qt::QueuedConnection); + connect(m_interface,SIGNAL(deviceNameChanged(QString, QString, int)), this, SLOT(onDeviceNameChanged(QString, QString, int)), Qt::QueuedConnection); + connect(m_interface,SIGNAL(hotspotDeactivated(QString, QString)), this, SLOT(onHotspotDeactivated(QString, QString)), Qt::QueuedConnection); + connect(m_interface,SIGNAL(hotspotActivated(QString, QString, QString)), this, SLOT(onHotspotActivated(QString, QString, QString)), Qt::QueuedConnection); + + connect(m_interface, SIGNAL(wlanactiveConnectionStateChanged(QString, QString, QString, int)), this, SLOT(onActiveConnectionChanged(QString, QString, QString, int)), Qt::QueuedConnection); + } + + if (QGSettings::isSchemaInstalled(GSETTINGS_SCHEMA)) { + m_switchGsettings = new QGSettings(GSETTINGS_SCHEMA); + onGsettingChanged(WIRELESS_SWITCH); + connect(m_switchGsettings, &QGSettings::changed, this, &MobileHotspotWidget::onGsettingChanged, Qt::QueuedConnection); + } + + connect(m_apNameLine, &QLineEdit::textEdited, this, &MobileHotspotWidget::onApLineEditTextEdit); +} + +void MobileHotspotWidget::onApLineEditTextEdit(QString text) +{ + int count = 0; + int i = 0; + + for ( ; i < text.length(); ++i) { + count += text.mid(i,1).toLocal8Bit().length(); + if (count > AP_NAME_MAX_LENGTH) { + break; + } + } + + m_apNameLine->setText(text.left(i)); +} + + +void MobileHotspotWidget::onActiveConnectionChanged(QString deviceName, QString ssid, QString uuid, int status) +{ + if(m_uuid == uuid && status == 4) { + showDesktopNotify(tr("hotspot already close")); + m_switchBtn->setChecked(false); + setUiEnabled(false); + m_uuid.clear(); + } +} + +void MobileHotspotWidget::onGsettingChanged(const QString &key) +{ + if (key == WIRELESS_SWITCH) { + bool status = m_switchGsettings->get(WIRELESS_SWITCH).toBool(); + if (!status) { +// if (m_switchBtn->isChecked()) { +// if(m_interface->isValid()) { +// QDBusReply reply = m_interface->call("deactiveWirelessAp", +// m_apNameLine->text(), +// m_pwdNameLine->text(), +// m_interfaceComboBox->currentText()); +// if (!reply.isValid()) { +// qDebug() << "[MobileHotspotWidget] call deactiveWirelessAp failed "; +// return true; +// } +// } +// } + m_switchBtn->setChecked(status); + m_uuid.clear(); + m_switchBtn->setDisabledFlag(true); + } else { + m_switchBtn->setDisabledFlag(false); + } + } +} + +void MobileHotspotWidget::initInterfaceInfo() +{ + if(!m_interface->isValid()) { + return; + } + m_interfaceComboBox->clear(); + QDBusReply > reply = m_interface->call("getDeviceListAndEnabled",WIRELESS); + + if (!reply.isValid()) { + qDebug()<<"execute dbus method 'getDeviceListAndEnabled' is invalid in func initInterfaceInfo()"; + setWidgetHidden(true); + return; + } + QMap devMap = reply.value(); + + QDBusReply > capReply = m_interface->call("getWirelessDeviceCap"); + if (!capReply.isValid()) { + qDebug()<<"execute dbus method 'getWirelessDeviceCap' is invalid in func initInterfaceInfo()" < devCapMap = capReply.value(); + + + if (devMap.isEmpty()) { + qDebug() << "no wireless device"; + setWidgetHidden(true); + m_switchBtn->setDisabledFlag(true); + } else { + QMap::Iterator iter = devMap.begin(); + while (iter != devMap.end()) { + QString interfaceName = iter.key(); + if (devCapMap[interfaceName] & 0x01) { + m_interfaceComboBox->addItem(interfaceName); + } + iter++; + } + if (m_interfaceComboBox->count() > 0) { + setWidgetHidden(false); + m_interfaceName = m_interfaceComboBox->currentText(); + if (m_interfaceComboBox->count() == 1) { + updateBandCombox(); + } + } else { + qDebug() << "no useable wireless device"; + setWidgetHidden(true); + } + } +} + +void MobileHotspotWidget::getApInfo() +{ + if (!m_interface->isValid()) { + return; + } + + if (m_interfaceComboBox->count() <= 0) { + m_switchBtn->setChecked(false); + setWidgetHidden(true); + qWarning() << "getApInfo but interface is empty"; + return; + } + + + QDBusReply reply = m_interface->call("getStoredApInfo"); + if (!reply.isValid()) { + qDebug()<<"execute dbus method 'getStoredApInfo' is invalid in func getObjectPath()"; + } + + QStringList apInfo = reply.value(); + + if (apInfo.isEmpty()) { + qDebug() << "no stored hotspot info"; + m_apNameLine->setText(m_hostName); + m_pwdNameLine->setText("12345678"); + return; + } else { + int index = m_interfaceComboBox->findText(apInfo.at(2)); + if (index >= 0) { + m_apNameLine->setText(apInfo.at(0)); + m_pwdNameLine->setText(apInfo.at(1)); + m_interfaceComboBox->setCurrentIndex(index); + m_interfaceName = apInfo.at(2); + if (apInfo.at(3) == "true") { + m_switchBtn->setChecked(true); + setUiEnabled(true); + m_uuid = apInfo.at(4); + } else { + m_switchBtn->setChecked(false); + setUiEnabled(false); + } + } else { + qDebug() << "no such interface " << apInfo.at(2); + } + } +} + +void MobileHotspotWidget::setSwitchFrame() +{ + /* Open */ + m_switchFrame = new QFrame(this); + m_switchFrame->setFrameShape(QFrame::Shape::NoFrame); + m_switchFrame->setMinimumSize(FRAME_MIN_SIZE); + m_switchFrame->setMaximumSize(CONTECT_FRAME_MAX_SIZE); + + QHBoxLayout *switchLayout = new QHBoxLayout(); + + m_switchLabel = new QLabel(tr("Open"), this); + m_switchLabel->setMinimumWidth(LABLE_MIN_WIDTH); + m_switchBtn = new SwitchButton(this); + switchLayout->addSpacing(LAYOUT_LEFT_MARGINS); + switchLayout->addWidget(m_switchLabel); + switchLayout->addStretch(); + switchLayout->addWidget(m_switchBtn); + + m_switchFrame->setLayout(switchLayout); +} + +void MobileHotspotWidget::setApNameFrame() +{ + /* ApName */ + m_ApNameFrame = new QFrame(this); + m_ApNameFrame->setFrameShape(QFrame::Shape::NoFrame); + m_ApNameFrame->setMinimumSize(FRAME_MIN_SIZE); + m_ApNameFrame->setMaximumSize(CONTECT_FRAME_MAX_SIZE); + + QHBoxLayout *apNameHLayout = new QHBoxLayout(); + + m_apNameLabel = new QLabel(tr("Wi-Fi Name"), this); + m_apNameLabel->setMinimumWidth(LABLE_MIN_WIDTH); + m_apNameLine = new QLineEdit(this); + m_apNameLine->setMinimumWidth(COMBOBOX_MIN_WIDTH); + m_apNameLine->setMaxLength(AP_NAME_MAX_LENGTH); + apNameHLayout->addSpacing(LAYOUT_LEFT_MARGINS); + apNameHLayout->addWidget(m_apNameLabel); + apNameHLayout->addWidget(m_apNameLine); + m_ApNameFrame->setLayout(apNameHLayout); + +} + +void MobileHotspotWidget::setPasswordFrame() +{ + /* Password */ + m_passwordFrame = new QFrame(this); + m_passwordFrame->setFrameShape(QFrame::Shape::NoFrame); + m_passwordFrame->setMinimumSize(FRAME_MIN_SIZE); + m_passwordFrame->setMaximumSize(CONTECT_FRAME_MAX_SIZE); + + QHBoxLayout *passwordHLayout = new QHBoxLayout(); + + m_pwdLabel = new QLabel(tr("Password"), this); + m_pwdLabel->setMinimumWidth(LABLE_MIN_WIDTH); + m_pwdNameLine = new QLineEdit(this); + m_pwdNameLine->setMinimumWidth(COMBOBOX_MIN_WIDTH); + m_pwdNameLine->setEchoMode(QLineEdit::Password); + passwordHLayout->addSpacing(LAYOUT_LEFT_MARGINS); + passwordHLayout->addWidget(m_pwdLabel); + passwordHLayout->addWidget(m_pwdNameLine); + + m_passwordFrame->setLayout(passwordHLayout); + + m_pwdShowBox = new QPushButton(this); + m_pwdShowBox->setFlat(true); + m_pwdShowBox->setFixedSize(ICON_SIZE); + m_pwdShowBox->setIcon(QIcon::fromTheme("ukui-eye-hidden-symbolic")); + m_pwdShowBox->setCursor(Qt::PointingHandCursor); + //防止文本框输入内容位于按钮之下 + QMargins margins = m_pwdNameLine->textMargins(); + m_pwdNameLine->setTextMargins(margins.left(), margins.top(), m_pwdShowBox->width() + 10, margins.bottom()); + QHBoxLayout *pSearchLayout = new QHBoxLayout(); + pSearchLayout->addStretch(); + pSearchLayout->addWidget(m_pwdShowBox); + pSearchLayout->setSpacing(0); + pSearchLayout->setContentsMargins(0, 0, 10, 0); + m_pwdNameLine->setLayout(pSearchLayout); + m_pwdNameLine->setEchoMode(QLineEdit::Password); +} + +void MobileHotspotWidget::setFreqBandFrame() +{ + /* frequency band */ + m_freqBandFrame = new QFrame(this); + m_freqBandFrame->setFrameShape(QFrame::Shape::NoFrame); + m_freqBandFrame->setMinimumSize(FRAME_MIN_SIZE); + m_freqBandFrame->setMaximumSize(CONTECT_FRAME_MAX_SIZE); + + QHBoxLayout *freqBandHLayout = new QHBoxLayout(); + + m_freqBandLabel = new QLabel(tr("Frequency band"), this); + m_freqBandLabel->setMinimumWidth(LABLE_MIN_WIDTH); + m_freqBandComboBox = new QComboBox(this); + m_freqBandComboBox->setInsertPolicy(QComboBox::NoInsert); + m_freqBandComboBox->setMinimumWidth(COMBOBOX_MIN_WIDTH); + m_freqBandComboBox->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed); + m_freqBandComboBox->addItem("2.4Ghz"); + m_freqBandComboBox->addItem("5Ghz"); + freqBandHLayout->addSpacing(LAYOUT_LEFT_MARGINS); + freqBandHLayout->addWidget(m_freqBandLabel); + freqBandHLayout->addWidget(m_freqBandComboBox); + + m_freqBandFrame->setLayout(freqBandHLayout); +} + +void MobileHotspotWidget::setInterFaceFrame() +{ + /* key tips */ + m_interfaceFrame = new QFrame(this); + m_interfaceFrame->setFrameShape(QFrame::Shape::NoFrame); + m_interfaceFrame->setMinimumSize(FRAME_MIN_SIZE); + m_interfaceFrame->setMaximumSize(CONTECT_FRAME_MAX_SIZE); + + QHBoxLayout *interfaceHLayout = new QHBoxLayout; + + m_interfaceLabel = new QLabel(tr("Net card"), this); + m_interfaceLabel->setMinimumWidth(LABLE_MIN_WIDTH); + m_interfaceComboBox = new QComboBox(this); + m_interfaceComboBox->setInsertPolicy(QComboBox::NoInsert); + m_interfaceComboBox->setMinimumWidth(COMBOBOX_MIN_WIDTH); + m_interfaceComboBox->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed); + interfaceHLayout->addSpacing(LAYOUT_LEFT_MARGINS); + interfaceHLayout->addWidget(m_interfaceLabel); + interfaceHLayout->addWidget(m_interfaceComboBox); + + m_interfaceFrame->setLayout(interfaceHLayout); +} + +void MobileHotspotWidget::onActivateFailed(QString errorMessage) +{ + if (errorMessage.indexOf("hotspot")) { + //todo +// showDesktopNotify(errorMessage); + } +} + +void MobileHotspotWidget::onDeactivateFailed(QString errorMessage) +{ + if (errorMessage.indexOf("hotspot")) { +// showDesktopNotify(errorMessage); + } +} + +//设备插拔 +void MobileHotspotWidget::onDeviceStatusChanged() +{ + initInterfaceInfo(); + getApInfo(); +} + +void MobileHotspotWidget::onDeviceNameChanged(QString oldName, QString newName, int type) +{ + if (WIRELESS != type) { + return; + } + int index = m_interfaceComboBox->findText(oldName); + if (index >= 0) { + m_interfaceComboBox->setItemText(index, newName); + if (m_interfaceName == oldName) { + m_interfaceName = newName; + } + } +} + +//热点断开 +void MobileHotspotWidget::onHotspotDeactivated(QString devName, QString ssid) +{ + if (!m_switchBtn->isChecked()) { + return; + } + if (devName == m_interfaceComboBox->currentText() && ssid == m_apNameLine->text()) { + m_switchBtn->setChecked(false); + m_uuid.clear(); +// setUiEnabled(true); + showDesktopNotify(tr("hotspot already close")); + } +} + +//热点连接 +void MobileHotspotWidget::onHotspotActivated(QString devName, QString ssid, QString uuid) +{ + qDebug() << "onHotspotActivated" <isChecked()) { + return; + } + + if (devName == m_interfaceComboBox->currentText() && ssid == m_apNameLine->text()) { + m_switchBtn->setChecked(true); + m_uuid = uuid; +// setUiEnabled(false); + showDesktopNotify(tr("hotspot already open")); + } else { + QStringList info; + if (!getApInfoBySsid(devName, ssid, info)) { + return; + } + int index = m_interfaceComboBox->findText(devName); + if (index >= 0) { + showDesktopNotify(tr("hotspot already open")); + m_apNameLine->setText(ssid); + m_interfaceComboBox->setCurrentIndex(index); + m_switchBtn->setChecked(true); + m_switchBtn->setDisabledFlag(false); + m_pwdNameLine->setText(info.at(0)); + m_interfaceName = devName; + updateBandCombox(); + index = m_freqBandComboBox->findText(info.at(1)); + if (index >= 0) { + m_freqBandComboBox->setCurrentIndex(index); + } + m_uuid = uuid; + } else { + qDebug() << "no such device in combo box"; + } + } +} + +bool MobileHotspotWidget::getApInfoBySsid(QString devName, QString ssid, QStringList &info) +{ + info.clear(); + if(!m_interface->isValid()) { + return false; + } + QDBusReply reply = m_interface->call("getApInfoBySsid", devName, ssid); + if (!reply.isValid()) { + qDebug()<<"execute dbus method 'getApInfoBySsid' is invalid in func getApInfoBySsid()"; + } + info = reply.value(); + if (info.size() != 2) { + return false; + } else { + return true; + } +} + +void MobileHotspotWidget::setUiEnabled(bool enable) +{ + qDebug() << "switch mode change to " << enable; + if (enable) { + m_pwdNameLine->setEnabled(false); + m_freqBandComboBox->setEnabled(false); + m_interfaceComboBox->setEnabled(false); + m_apNameLine->setEnabled(false); + } else { + m_pwdNameLine->setEnabled(true); + m_freqBandComboBox->setEnabled(true); + m_interfaceComboBox->setEnabled(true); + m_apNameLine->setEnabled(true); + } +} + +void MobileHotspotWidget::setWidgetHidden(bool isHidden) +{ + m_ApNameFrame->setHidden(isHidden); + m_passwordFrame->setHidden(isHidden); + m_freqBandFrame->setHidden(isHidden); + m_interfaceFrame->setHidden(isHidden); + + switchAndApNameLine->setHidden(isHidden); + apNameAndPwdLine->setHidden(isHidden); + pwdAndfreqBandLine->setHidden(isHidden); + freqBandAndInterfaceLine->setHidden(isHidden); + + if (isHidden) { + m_switchBtn->setChecked(false); + m_switchBtn->setDisabledFlag(true); + m_interfaceName = ""; + m_uuid = ""; + } else { + m_switchBtn->setDisabledFlag(false); + onGsettingChanged(WIRELESS_SWITCH); + } + +} + +void MobileHotspotWidget::updateBandCombox() +{ + m_freqBandComboBox->clear(); + QDBusReply > capReply = m_interface->call("getWirelessDeviceCap"); + if (!capReply.isValid()) { + qDebug()<<"execute dbus method 'getWirelessDeviceCap' is invalid in func initInterfaceInfo()" << capReply.error().message(); + setWidgetHidden(true); + return; + } + QMap devCapMap = capReply.value(); + if (devCapMap[m_interfaceName] & 0x02) { + m_freqBandComboBox->addItem("2.4Ghz"); + } + if (devCapMap[m_interfaceName] & 0x04) { + m_freqBandComboBox->addItem("5Ghz"); + } +} + +QFrame* MobileHotspotWidget::myLine() +{ + QFrame *line = new QFrame(this); + line->setMinimumSize(QSize(LINE_MIN_SIZE)); + line->setMaximumSize(QSize(LINE_MAX_SIZE)); + line->setLineWidth(0); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + + return line; +} + +QString MobileHotspotWidget::getHostName() +{ + int count = 0; + while (count < 3) { + QDBusInterface hostInterface("org.freedesktop.hostname1", + "/org/freedesktop/hostname1", + "org.freedesktop.hostname1", + QDBusConnection::systemBus()); + if (hostInterface.isValid()) { + return hostInterface.property("Hostname").value(); + } else { + count++; + } + } + return "default"; +} diff --git a/plugins/mobilehotspot/mobilehotspotwidget.h b/plugins/mobilehotspot/mobilehotspotwidget.h new file mode 100644 index 00000000..cd21d00f --- /dev/null +++ b/plugins/mobilehotspot/mobilehotspotwidget.h @@ -0,0 +1,119 @@ +#ifndef MOBILEHOTSPOTWIDGET_H +#define MOBILEHOTSPOTWIDGET_H + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +#include +#include +#include +#include +#include + +#include "switchbutton.h" +#include "titlelabel.h" + +class MobileHotspotWidget : public QWidget +{ + Q_OBJECT +public: + explicit MobileHotspotWidget(QWidget *parent = nullptr); + ~MobileHotspotWidget(); + +private: + QFrame *m_switchFrame = nullptr; //开关 + QFrame *m_ApNameFrame = nullptr; //wifi名称 + QFrame *m_passwordFrame = nullptr; //密码 + QFrame *m_freqBandFrame = nullptr; //频带 + QFrame *m_interfaceFrame = nullptr; //网卡 + + SwitchButton *m_switchBtn; + + TitleLabel *m_hotspotTitleLabel; + QLabel *m_switchLabel; + QLabel *m_apNameLabel; + QLabel *m_pwdLabel; + QLabel *m_freqBandLabel; + QLabel *m_interfaceLabel; + + + QPushButton *m_pwdShowBox; + + QFrame *switchAndApNameLine; + QFrame *apNameAndPwdLine; + QFrame *pwdAndfreqBandLine; + QFrame *freqBandAndInterfaceLine; + + QVBoxLayout *mVlayout; + + QLineEdit *m_apNameLine; + QLineEdit *m_pwdNameLine; + + QComboBox *m_freqBandComboBox; + QComboBox *m_interfaceComboBox; + + QDBusInterface *m_interface = nullptr; + + QString m_interfaceName = ""; + + QGSettings *m_switchGsettings = nullptr; + + QString m_uuid = ""; + QString m_hostName = ""; + + void initUI(); + void initDbusConnect(); + void initInterfaceInfo(); + void getApInfo(); + bool getApInfoBySsid(QString devName, QString ssid, QStringList &info); + void setSwitchFrame(); + void setApNameFrame(); + void setPasswordFrame(); + void setFreqBandFrame(); + void setInterFaceFrame(); + + void setUiEnabled(bool enable); + void setWidgetHidden(bool isHidden); + + void showDesktopNotify(const QString &message); + + void updateBandCombox(); + + QString getHostName(); + + bool eventFilter(QObject *watched, QEvent *event); + void paintEvent(QPaintEvent *event); + + QFrame* myLine(); + +signals: + +private slots: + void onActivateFailed(QString errorMessage); + void onDeactivateFailed(QString errorMessage); + //设备插拔 + void onDeviceStatusChanged(); + void onDeviceNameChanged(QString oldName, QString newName, int type); + //热点断开 + void onHotspotDeactivated(QString devName, QString ssid); + //热点连接 + void onHotspotActivated(QString devName, QString ssid, QString uuid); + + void onGsettingChanged(const QString &key); + + void onActiveConnectionChanged(QString deviceName, QString ssid, QString uuid, int status); + + void onApLineEditTextEdit(QString text); + +}; + +#endif // MOBILEHOTSPOTWIDGET_H diff --git a/plugins/mobilehotspot/translations/bo.qm b/plugins/mobilehotspot/translations/bo.qm new file mode 100644 index 00000000..be651eed --- /dev/null +++ b/plugins/mobilehotspot/translations/bo.qm @@ -0,0 +1 @@ + + + + + MobileHotspot + + + MobileHotspot + + + + + mobilehotspot + + /mobilehotspot/mobilehotspot + + + + mobilehotspot open + + /mobilehotspot/mobilehotspot open + + + + MobileHotspotWidget + + + ukui control center + + + + + ukui control center desktop message + + + + + wirless switch is close or no wireless device + + + + + start to close hotspot + + + + + hotpots name or device is invalid + + + + + can not create hotspot with password length less than eight! + + + + + start to open hotspot + + + + + Hotspot + + + + + + hotspot already close + + + + + Open + + + + + Wi-Fi Name + + + + + Password + + + + + Frequency band + + + + + Net card + + + + + + hotspot already open + + + + diff --git a/plugins/mobilehotspot/translations/tr.qm b/plugins/mobilehotspot/translations/tr.qm new file mode 100644 index 00000000..be651eed --- /dev/null +++ b/plugins/mobilehotspot/translations/tr.qm @@ -0,0 +1 @@ + + + + + MobileHotspot + + + MobileHotspot + + + + + mobilehotspot + + /mobilehotspot/mobilehotspot + + + + mobilehotspot open + + /mobilehotspot/mobilehotspot open + + + + MobileHotspotWidget + + + ukui control center + + + + + ukui control center desktop message + + + + + wirless switch is close or no wireless device + + + + + start to close hotspot + + + + + hotpots name or device is invalid + + + + + can not create hotspot with password length less than eight! + + + + + start to open hotspot + + + + + Hotspot + + + + + + hotspot already close + + + + + Open + + + + + Wi-Fi Name + + + + + Password + + + + + Frequency band + + + + + Net card + + + + + + hotspot already open + + + + diff --git a/plugins/mobilehotspot/translations/zh_CN.qm b/plugins/mobilehotspot/translations/zh_CN.qm new file mode 100644 index 00000000..52e6c4f8 Binary files /dev/null and b/plugins/mobilehotspot/translations/zh_CN.qm differ diff --git a/plugins/mobilehotspot/translations/zh_CN.ts b/plugins/mobilehotspot/translations/zh_CN.ts new file mode 100644 index 00000000..0867a0ec --- /dev/null +++ b/plugins/mobilehotspot/translations/zh_CN.ts @@ -0,0 +1,104 @@ + + + + + MobileHotspot + + + MobileHotspot + 移动热点 + + + + mobilehotspot + 移动热点 + /mobilehotspot/mobilehotspot + + + + mobilehotspot open + 移动热点 开启 + /mobilehotspot/mobilehotspot open + + + + MobileHotspotWidget + + + ukui control center + 控制面板 + + + + ukui control center desktop message + 控制面板桌面通知 + + + + wirless switch is close or no wireless device + 无线开关已关闭或不存在有热点功能的无线网卡 + + + + start to close hotspot + 开始关闭热点 + + + + hotpots name or device is invalid + 热点名称或设备错误 + + + + can not create hotspot with password length less than eight! + 不能创建密码长度小于八位的热点! + + + + start to open hotspot + 开始创建热点 + + + + Hotspot + 移动热点 + + + + + hotspot already close + 热点已关闭 + + + + Open + 开启 + + + + Wi-Fi Name + Wi-Fi名称 + + + + Password + 网络密码 + + + + Frequency band + 网络频带 + + + + Net card + 共享网卡端口 + + + + + hotspot already open + 热点已开启 + + + diff --git a/plugins/netconnect/addnetbtn.cpp b/plugins/netconnect/addnetbtn.cpp new file mode 100644 index 00000000..d0a14714 --- /dev/null +++ b/plugins/netconnect/addnetbtn.cpp @@ -0,0 +1,70 @@ +#include "addnetbtn.h" +#include +#include +#include +#include +#include +#include + +#define RADIUS 6.0 + +AddNetBtn::AddNetBtn(QWidget *parent) : QPushButton(parent) +{ + this->setObjectName("this"); + this->setMinimumSize(QSize(580, 60)); + this->setMaximumSize(QSize(16777215, 60)); + this->setStyleSheet("QPushButton:!checked{background-color: palette(base)}"); + this->setProperty("useButtonPalette", true); + + QHBoxLayout *addLyt = new QHBoxLayout; + + QLabel *iconLabel = new QLabel(); + QLabel *textLabel = new QLabel(tr("Add WiredNetork")); + + QIcon mAddIcon = QIcon::fromTheme("list-add-symbolic"); + iconLabel->setPixmap(mAddIcon.pixmap(mAddIcon.actualSize(QSize(24, 24)))); + iconLabel->setProperty("useIconHighlightEffect", true); + iconLabel->setProperty("iconHighlightEffectMode", 1); + + addLyt->addStretch(); + addLyt->addWidget(iconLabel); + addLyt->addWidget(textLabel); + addLyt->addStretch(); + this->setLayout(addLyt); + +} + +AddNetBtn::~AddNetBtn() +{ + +} + +void AddNetBtn::enterEvent(QEvent *event){ + Q_EMIT enterWidget(); + + QPushButton::enterEvent(event); +} + +void AddNetBtn::leaveEvent(QEvent *event){ + Q_EMIT leaveWidget(); + + QPushButton::leaveEvent(event); +} + +void AddNetBtn::paintEvent(QPaintEvent *event) +{ + QPalette pal = this->palette(); + + QPainter painter(this); + painter.setRenderHint(QPainter:: Antialiasing, true); //设置渲染,启动反锯齿 + painter.setPen(Qt::NoPen); + painter.setBrush(pal.color(QPalette::Base)); + + QRect rect = this->rect(); + QPainterPath path; + path.addRoundedRect (rect, RADIUS, RADIUS); + QRect temp_rect(rect.left(), rect.top(), rect.width(), rect.height()/2); + path.addRect(temp_rect); + painter.drawPath(path); + QPushButton::paintEvent(event); +} diff --git a/plugins/netconnect/addnetbtn.h b/plugins/netconnect/addnetbtn.h new file mode 100644 index 00000000..d989a150 --- /dev/null +++ b/plugins/netconnect/addnetbtn.h @@ -0,0 +1,27 @@ +#ifndef ADDNETBTN_H +#define ADDNETBTN_H + +#include +#include +#include +#include +#include + +class AddNetBtn : public QPushButton +{ + Q_OBJECT +public: + AddNetBtn(QWidget *parent = nullptr); + ~AddNetBtn(); + +protected: + virtual void leaveEvent(QEvent * event); + virtual void enterEvent(QEvent * event); + void paintEvent(QPaintEvent *event); + +Q_SIGNALS: + void enterWidget(); + void leaveWidget(); +}; + +#endif // ADDNETBTN_H diff --git a/plugins/netconnect/deviceframe.cpp b/plugins/netconnect/deviceframe.cpp new file mode 100644 index 00000000..12b59f69 --- /dev/null +++ b/plugins/netconnect/deviceframe.cpp @@ -0,0 +1,46 @@ +#include "deviceframe.h" + +#define LAYOUT_MARGINS 18,0,24,0 +#define FRAME_HEIGHT 58 +#define RADIUS 6.0 + +DeviceFrame::DeviceFrame(QString devName, QWidget *parent) : QFrame(parent) +{ + this->setFrameShape(QFrame::Box); + this->setFixedHeight(FRAME_HEIGHT); + QHBoxLayout *deviceLayout = new QHBoxLayout(this); + deviceLayout->setContentsMargins(LAYOUT_MARGINS); + setLayout(deviceLayout); + + deviceLabel = new QLabel(this); + dropDownLabel = new DrownLabel(devName, this); + deviceSwitch = new SwitchButton(this); + + deviceLayout->addWidget(deviceLabel); + deviceLayout->addStretch(); + deviceLayout->addWidget(dropDownLabel); + deviceLayout->addWidget(deviceSwitch); +} + +DeviceFrame::~DeviceFrame() +{ + +} + +void DeviceFrame::paintEvent(QPaintEvent *event) +{ + QPalette pal = this->palette(); + + QPainter painter(this); + painter.setRenderHint(QPainter:: Antialiasing, true); //设置渲染,启动反锯齿 + painter.setPen(Qt::NoPen); + painter.setBrush(pal.color(QPalette::Base)); + + QRect rect = this->rect(); + QPainterPath path; + path.addRoundedRect (rect, RADIUS, RADIUS); + QRect temp_rect(rect.left(), rect.top() + rect.height()/2, rect.width(), rect.height()/2); + path.addRect(temp_rect); + painter.drawPath(path); + QFrame::paintEvent(event); +} diff --git a/plugins/netconnect/deviceframe.h b/plugins/netconnect/deviceframe.h new file mode 100644 index 00000000..5834b62c --- /dev/null +++ b/plugins/netconnect/deviceframe.h @@ -0,0 +1,33 @@ +#ifndef DEVICEFRAME_H +#define DEVICEFRAME_H +#include +#include +#include +#include +#include +#include +#include +#include "switchbutton.h" +#include "../component/DrownLabel/drownlabel.h" + +class DeviceFrame : public QFrame +{ + +public: + DeviceFrame(QString devName, QWidget *parent = nullptr); + ~DeviceFrame(); +public: + QLabel * deviceLabel = nullptr; + SwitchButton * deviceSwitch = nullptr; + DrownLabel *dropDownLabel = nullptr; + +protected: + void paintEvent(QPaintEvent *event); + +private: + bool isDropDown = false; + int frameSize; + +}; + +#endif // DEVICEFRAME_H diff --git a/plugins/netconnect/itemframe.cpp b/plugins/netconnect/itemframe.cpp new file mode 100644 index 00000000..c144e80e --- /dev/null +++ b/plugins/netconnect/itemframe.cpp @@ -0,0 +1,47 @@ +#include "itemframe.h" + +#include +#include + +#define LAYOUT_MARGINS 0,0,0,0 +#define MAIN_LAYOUT_MARGINS 0,0,0,0 +ItemFrame::ItemFrame(QString devName, QWidget *parent) : QFrame(parent) +{ + deviceLanLayout = new QVBoxLayout(this); + deviceLanLayout->setContentsMargins(MAIN_LAYOUT_MARGINS); + lanItemFrame = new QFrame(this); + lanItemFrame->setFrameShape(QFrame::Shape::NoFrame); + + lanItemLayout = new QVBoxLayout(this); + lanItemLayout->setContentsMargins(LAYOUT_MARGINS); + lanItemLayout->setSpacing(1); + addLanWidget = new AddNetBtn(this); + + deviceLanLayout->setSpacing(1); + setLayout(deviceLanLayout); + lanItemFrame->setLayout(lanItemLayout); + + deviceFrame = new DeviceFrame(devName, this); + deviceLanLayout->addWidget(deviceFrame); + deviceLanLayout->addWidget(lanItemFrame); + deviceLanLayout->addWidget(addLanWidget); + + //下拉按钮 + connect(deviceFrame->dropDownLabel, &DrownLabel::labelClicked, this, &ItemFrame::onDrownLabelClicked); +} + +ItemFrame::~ItemFrame() +{ + +} + +void ItemFrame::onDrownLabelClicked() +{ + if (!deviceFrame->dropDownLabel->isChecked) { + lanItemFrame->show(); + deviceFrame->dropDownLabel->setDropDownStatus(true); + } else { + lanItemFrame->hide(); + deviceFrame->dropDownLabel->setDropDownStatus(false); + } +} diff --git a/plugins/netconnect/itemframe.h b/plugins/netconnect/itemframe.h new file mode 100644 index 00000000..20b23931 --- /dev/null +++ b/plugins/netconnect/itemframe.h @@ -0,0 +1,33 @@ +#ifndef ITEMFRAME_H +#define ITEMFRAME_H +#include +#include +#include "deviceframe.h" +#include +#include "addnetbtn.h" +#include "lanitem.h" + +class ItemFrame : public QFrame +{ + Q_OBJECT +public: + ItemFrame(QString devName, QWidget *parent = nullptr); + ~ItemFrame(); + //单设备整体layout + QVBoxLayout * deviceLanLayout = nullptr; + //单设备名称+下拉按钮Frame+d单设备开关 + DeviceFrame * deviceFrame = nullptr; + //单设备列表Frame + QFrame * lanItemFrame = nullptr; + //单设备列表layout + QVBoxLayout * lanItemLayout = nullptr; + //新建有线连接 + AddNetBtn * addLanWidget = nullptr; + //单设备item列表 key:uuid + QMap itemMap; + +private slots: + void onDrownLabelClicked(); +}; + +#endif // ITEMFRAME_H diff --git a/plugins/netconnect/lanitem.cpp b/plugins/netconnect/lanitem.cpp new file mode 100644 index 00000000..5d33d983 --- /dev/null +++ b/plugins/netconnect/lanitem.cpp @@ -0,0 +1,81 @@ +#include "lanitem.h" +#define FRAME_SPEED 150 +#define LIMIT_TIME 60*1000 +#define TOTAL_PAGE 8 + +#define THEME_QT_SCHEMA "org.ukui.style" +#define MODE_QT_KEY "style-name" + +LanItem::LanItem(bool isAcitve, QWidget *parent) + : QPushButton(parent),isAcitve(isAcitve) +{ + this->setMinimumSize(550, 58); + this->setProperty("useButtonPalette", true); + setStyleSheet("QPushButton:!checked{background-color: palette(base)}"); + QHBoxLayout *mLanLyt = new QHBoxLayout(this); + mLanLyt->setContentsMargins(16,0,16,0); + mLanLyt->setSpacing(16); + iconLabel = new QLabel(this); + iconLabel->setProperty("useIconHighlightEffect", 0x2); + titileLabel = new FixLabel(this); + statusLabel = new QLabel(this); + statusLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); +// statusLabel->setMinimumSize(36,36); + infoLabel = new InfoButton(this); + mLanLyt->addWidget(iconLabel); + mLanLyt->addWidget(titileLabel,Qt::AlignLeft); + mLanLyt->addStretch(); + mLanLyt->addWidget(statusLabel); + mLanLyt->addWidget(infoLabel); + + loadIcons.append(QIcon::fromTheme("ukui-loading-1-symbolic")); + loadIcons.append(QIcon::fromTheme("ukui-loading-2-symbolic")); + loadIcons.append(QIcon::fromTheme("ukui-loading-3-symbolic")); + loadIcons.append(QIcon::fromTheme("ukui-loading-4-symbolic")); + loadIcons.append(QIcon::fromTheme("ukui-loading-5-symbolic")); + loadIcons.append(QIcon::fromTheme("ukui-loading-6-symbolic")); + loadIcons.append(QIcon::fromTheme("ukui-loading-7-symbolic")); + waitTimer = new QTimer(this); + connect(waitTimer, &QTimer::timeout, this, &LanItem::updateIcon); +} + +LanItem::~LanItem() +{ + +} + +void LanItem::updateIcon() +{ + if (currentIconIndex > 6) { + currentIconIndex = 0; + } + statusLabel->setPixmap(loadIcons.at(currentIconIndex).pixmap(16,16)); + currentIconIndex ++; +} + +void LanItem::startLoading() +{ + waitTimer->start(FRAME_SPEED); + loading = true; +} + +void LanItem::stopLoading(){ + waitTimer->stop(); + loading = false; +} + +void LanItem::paintEvent(QPaintEvent *event) +{ + QPalette pal = this->palette(); + + QPainter painter(this); + painter.setRenderHint(QPainter:: Antialiasing, true); //设置渲染,启动反锯齿 + painter.setPen(Qt::NoPen); + painter.setBrush(pal.color(QPalette::Base)); + + QRect rect = this->rect(); + + painter.drawRect(rect); + QPushButton::paintEvent(event); +} + diff --git a/plugins/netconnect/lanitem.h b/plugins/netconnect/lanitem.h new file mode 100644 index 00000000..dbaacb04 --- /dev/null +++ b/plugins/netconnect/lanitem.h @@ -0,0 +1,51 @@ +#ifndef LANITEM_H +#define LANITEM_H +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fixlabel.h" +#include "infobutton.h" + +class LanItem : public QPushButton +{ +public: + LanItem(bool isAcitve, QWidget *parent = nullptr); + ~LanItem(); +public: + QLabel * iconLabel = nullptr; + InfoButton * infoLabel = nullptr; + FixLabel * titileLabel = nullptr; + QLabel * statusLabel = nullptr; + +public: + void startLoading(); + void stopLoading(); + + bool loading = false; + bool isAcitve = false; + + QString uuid; + QString dbusPath; + +protected: + void paintEvent(QPaintEvent *); + +private: + QTimer *waitTimer = nullptr; + QGSettings *themeGsettings = nullptr; + QList loadIcons; + int currentIconIndex=0; + +private slots: + void updateIcon(); + +}; + +#endif // LANITEM_H diff --git a/plugins/netconnect/netconnect.cpp b/plugins/netconnect/netconnect.cpp new file mode 100644 index 00000000..b4c0c240 --- /dev/null +++ b/plugins/netconnect/netconnect.cpp @@ -0,0 +1,883 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. + * + * 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 "netconnect.h" +#include "ui_netconnect.h" + +#include +#include +#include +#include +#include +#include +#include + +#define WIRED_TYPE 0 +#define ITEMHEIGH 50 +#define LAN_TYPE 0 +#define CONTROL_CENTER_WIFI "org.ukui.control-center.wifi.switch" + +const QString KLanSymbolic = "network-wired-connected-symbolic"; +const QString NoNetSymbolic = "network-wired-disconnected-symbolic"; + +const QString WIRED_SWITCH = "wiredswitch"; +const QByteArray GSETTINGS_SCHEMA = "org.ukui.kylin-nm.switch"; + +#define ACTIVATING 1 +#define ACTIVATED 2 +#define DEACTIVATING 3 +#define DEACTIVATED 4 + +#define NO_MARGINS 0,0,0,0 +#define TOP_MARGINS 0,8,0,0 +#define MAIN_LAYOUT_MARGINS 0,0,0,8 +#define SPACING 8 + +bool sortByVal(const QPair &l, const QPair &r) { + return (l.second < r.second); +} + +void NetConnect::showDesktopNotify(const QString &message) +{ + QDBusInterface iface("org.freedesktop.Notifications", + "/org/freedesktop/Notifications", + "org.freedesktop.Notifications", + QDBusConnection::sessionBus()); + QList args; + args<<(tr("ukui control center")) + <<((unsigned int) 0) + <load("/usr/share/kylin-nm/netconnect/" + QLocale::system().name()); + QApplication::installTranslator(translator); + + pluginName = tr("WiredConnect"); + pluginType = NETWORK; +} + +NetConnect::~NetConnect() { + if (!mFirstLoad) { + delete ui; + ui = nullptr; + delete m_interface; + delete m_switchGsettings; + } +} + +QString NetConnect::plugini18nName() { + return pluginName; +} + +int NetConnect::pluginTypes() { + return pluginType; +} + +QWidget *NetConnect::pluginUi() { + if (mFirstLoad) { + mFirstLoad = false; + + ui = new Ui::NetConnect; + pluginWidget = new QWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(pluginWidget); + qDBusRegisterMetaType>(); + m_interface = new QDBusInterface("com.kylin.network", + "/com/kylin/network", + "com.kylin.network", + QDBusConnection::sessionBus()); + if(!m_interface->isValid()) { + qWarning() << qPrintable(QDBusConnection::sessionBus().lastError().message()); + } + initSearchText(); + initComponent(); + } + return pluginWidget; +} + +const QString NetConnect::name() const { + + return QStringLiteral("netconnect"); +} + +bool NetConnect::isEnable() const +{ + return true; +} + + +bool NetConnect::isShowOnHomePage() const +{ + return false; +} + +QIcon NetConnect::icon() const +{ + return QIcon(); +} + +QString NetConnect::translationPath() const +{ + return "/usr/share/kylin-nm/netconnect/%1.ts"; +} + +void NetConnect::initSearchText() { + //~ contents_path /netconnect/Advanced settings" + ui->detailBtn->setText(tr("Advanced settings")); + ui->titleLabel->setText(tr("Wired Network")); + //~ contents_path /netconnect/open + ui->openLabel->setText(tr("open")); +} + +bool NetConnect::eventFilter(QObject *w, QEvent *e) { + if (e->type() == QEvent::Enter) { + if (w->findChild()) + w->findChild()->setStyleSheet("QWidget{background: palette(button);border-radius:4px;}"); + } else if (e->type() == QEvent::Leave) { + if (w->findChild()) + w->findChild()->setStyleSheet("QWidget{background: palette(base);border-radius:4px;}"); + } + return QObject::eventFilter(w,e); +} + +void NetConnect::initComponent() { + wiredSwitch = new SwitchButton(pluginWidget); + ui->openWIifLayout->addWidget(wiredSwitch); + ui->detailLayOut->setContentsMargins(MAIN_LAYOUT_MARGINS); + ui->verticalLayout_3->setContentsMargins(NO_MARGINS); + ui->availableLayout->setSpacing(SPACING); + ui->horizontalLayout->setContentsMargins(TOP_MARGINS); + + connect(wiredSwitch, &SwitchButton::disabledClick, this, [=]() { + showDesktopNotify(tr("No ethernet device avaliable")); + }); + + if (QGSettings::isSchemaInstalled(GSETTINGS_SCHEMA)) { + m_switchGsettings = new QGSettings(GSETTINGS_SCHEMA); + connect(wiredSwitch, &SwitchButton::checkedChanged, this, [=] (bool checked) { + if (!m_interface->isValid()) { + return; + } + if (wiredSwitch->getDisabledFlag()) { + return; + } + qDebug() << "[NetConnect]call setWiredSwitchEnable" << checked << __LINE__; + m_interface->call(QStringLiteral("setWiredSwitchEnable"),checked); + qDebug() << "[NetConnect]call setWiredSwitchEnable Respond" << __LINE__; + }); + setSwitchStatus(); + connect(m_switchGsettings, &QGSettings::changed, this, [=] (const QString &key) { + if (key == WIRED_SWITCH) { + setSwitchStatus(); + } + }); + } else { + wiredSwitch->blockSignals(true); + wiredSwitch->setChecked(true); + wiredSwitch->blockSignals(false); + qDebug()<<"[Netconnect] org.ukui.kylin-nm.switch is not installed!"; + } + + getDeviceStatusMap(deviceStatusMap); + if (deviceStatusMap.isEmpty()) { + qDebug() << "[Netconnect] no device exist when init, set switch disable"; + wiredSwitch->setDisabledFlag(true); + wiredSwitch->setChecked(false); + } + initNet(); + + if (!wiredSwitch->isChecked() || deviceStatusMap.isEmpty() || !m_interface->isValid()) { + hideLayout(ui->availableLayout); + } + + + // 有线网络断开或连接时刷新可用网络列表 + connect(m_interface, SIGNAL(lanActiveConnectionStateChanged(QString, QString, int)), this, SLOT(onActiveConnectionChanged(QString, QString, int)), Qt::QueuedConnection); + //有线网络新增时添加网络 + connect(m_interface, SIGNAL(lanAdd(QString, QStringList)), this, SLOT(onLanAdd(QString, QStringList)), Qt::QueuedConnection); + //删除有线网络 + connect(m_interface, SIGNAL(lanRemove(QString)), this, SLOT(onLanRemove(QString)), Qt::QueuedConnection); + //更新有线网络 + connect(m_interface, SIGNAL(lanUpdate(QString, QStringList)), this, SLOT(updateLanInfo(QString, QStringList)),Qt::QueuedConnection); + //网卡插拔处理 + connect(m_interface, SIGNAL(deviceStatusChanged()), this, SLOT(onDeviceStatusChanged()),Qt::QueuedConnection); + //网卡name处理 + connect(m_interface, SIGNAL(deviceNameChanged(QString, QString, int)), this, SLOT(onDeviceNameChanged(QString, QString, int)),Qt::QueuedConnection); + + + connect(ui->detailBtn, &QPushButton::clicked, this, [=](bool checked) { + Q_UNUSED(checked) + runExternalApp(); + }); +} + +//获取网卡列表 +void NetConnect::getDeviceStatusMap(QMap &map) +{ + if (!m_interface->isValid()) { + return; + } + qDebug() << "[NetConnect]call getDeviceListAndEnabled" << __LINE__; + QDBusMessage result = m_interface->call(QStringLiteral("getDeviceListAndEnabled"),0); + qDebug() << "[NetConnect]call getDeviceListAndEnabled Respond" << __LINE__; + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "[NetConnect]getWiredDeviceList error:" << result.errorMessage(); + return; + } + auto dbusArg = result.arguments().at(0).value(); + dbusArg >> map; +} + +//lanUpdate +void NetConnect::updateLanInfo(QString deviceName, QStringList lanInfo) +{ + //she bei gui shu bian hua && you xian ming cheng bian hua + QMap::iterator iter; + for (iter = deviceFrameMap.begin(); iter != deviceFrameMap.end(); iter++) { + if (deviceName.isEmpty()) { + //变为无指定网卡,所有列表都要添加 + if (!iter.value()->itemMap.contains(lanInfo.at(1))) { + qDebug() << "[NetConnect]" << lanInfo.at(0) << " change to device none, add every list"; + addOneLanFrame(iter.value(), iter.key(), lanInfo); + } else { + if (iter.value()->itemMap[lanInfo.at(1)]->titileLabel->text() != lanInfo.at(0)) { + qDebug() << "[NetConnect]" << iter.key() + << iter.value()->itemMap[lanInfo.at(1)]->titileLabel->text() << "change to" << lanInfo.at(0); + iter.value()->itemMap[lanInfo.at(1)]->titileLabel->setText(lanInfo.at(0)); + } + } + } else { + if (iter.key() != deviceName) { + qDebug() << "[NetConnect]" << lanInfo.at(0) << " not belongs to " << iter.key(); + removeOneLanFrame(iter.value(), deviceName, lanInfo.at(1)); + } else { + if (!iter.value()->itemMap.contains(lanInfo.at(1))) { + qDebug() << "[NetConnect]" << lanInfo.at(0) << " now belongs to " << deviceName; + addOneLanFrame(iter.value(), deviceName, lanInfo); + } else { + qDebug() << "[NetConnect]" << deviceName + << iter.value()->itemMap[lanInfo.at(1)]->titileLabel->text() << "change to" << lanInfo.at(0); + if (iter.value()->itemMap[lanInfo.at(1)]->titileLabel->text() != lanInfo.at(0)) { + iter.value()->itemMap[lanInfo.at(1)]->titileLabel->setText(lanInfo.at(0)); + } + } + } + } + } +} + + +//总开关 +void NetConnect::setSwitchStatus() +{ + if (QGSettings::isSchemaInstalled(GSETTINGS_SCHEMA)) { + bool status = m_switchGsettings->get(WIRED_SWITCH).toBool(); + wiredSwitch->blockSignals(true); + wiredSwitch->setChecked(status); + wiredSwitch->blockSignals(false); + if (!status) { + hideLayout(ui->availableLayout); + } else { + showLayout(ui->availableLayout); + } + } else { + qDebug()<<"[netconnect] org.ukui.kylin-nm.switch is not installed!"; + } + +} + +//总体隐藏 +void NetConnect::hideLayout(QVBoxLayout * layout) { + for (int i = layout->layout()->count()-1; i >= 0; --i) + { + QLayoutItem *it = layout->layout()->itemAt(i); + ItemFrame *itemFrame = qobject_cast(it->widget()); + itemFrame->hide(); + } +} + +//总体显示 +void NetConnect::showLayout(QVBoxLayout * layout) { + for (int i = layout->layout()->count()-1; i >= 0; --i) + { + QLayoutItem *it = layout->layout()->itemAt(i); + ItemFrame *itemFrame = qobject_cast(it->widget()); + itemFrame->show(); + } +} + +//初始化 +void NetConnect::initNet() +{ + //先构建每个设备的列表头 + QStringList deviceList = deviceStatusMap.keys(); + for (int i = 0; i < deviceList.size(); ++i) { + addDeviceFrame(deviceList.at(i)); + } + //再填充每个设备的列表 + for (int i = 0; i < deviceList.size(); ++i) { + initNetListFromDevice(deviceList.at(i)); + } +} + +void NetConnect::runExternalApp() { + QString cmd = "nm-connection-editor"; + QProcess process(this); + process.startDetached(cmd); +} + +//激活 +void NetConnect::activeConnect(QString ssid, QString deviceName, int type) { + qDebug() << "[NetConnect]call activateConnect" << __LINE__; + m_interface->call(QStringLiteral("activateConnect"),type, deviceName, ssid); + qDebug() << "[NetConnect]call activateConnect respond" << __LINE__; +} + +//断开 +void NetConnect::deActiveConnect(QString ssid, QString deviceName, int type) { + qDebug() << "[NetConnect]call deActivateConnect" << __LINE__; + m_interface->call(QStringLiteral("deActivateConnect"),type, deviceName, ssid); + qDebug() << "[NetConnect]call deActivateConnect respond" << __LINE__; +} + +//初始化设备列表 网卡标号问题? +void NetConnect::initNetListFromDevice(QString deviceName) +{ + qDebug() << "[NetConnect]initNetListFromDevice " << deviceName; + if (!deviceFrameMap.contains(deviceName)) { + qDebug() << "[NetConnect]initNetListFromDevice " << deviceName << " not exist"; + return; + } + if (!m_interface->isValid()) { + return; + } + qDebug() << "[NetConnect]call getWiredList" << __LINE__; + QDBusMessage result = m_interface->call(QStringLiteral("getWiredList")); + qDebug() << "[NetConnect]call getWiredList respond" << __LINE__; + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "getWiredList error:" << result.errorMessage(); + return; + } + auto dbusArg = result.arguments().at(0).value(); + QMap> variantList; + dbusArg >> variantList; + if (variantList.size() == 0) { + qDebug() << "[NetConnect]initNetListFromDevice " << deviceName << " list empty"; + return; + } + QMap>::iterator iter; + + for (iter = variantList.begin(); iter != variantList.end(); iter++) { + if (deviceName == iter.key()) { + QVector wlanListInfo = iter.value(); + //处理列表 已连接 + qDebug() << "[NetConnect]initNetListFromDevice " << deviceName << " acitved lan " << wlanListInfo.at(0); + addLanItem(deviceFrameMap[deviceName], deviceName, wlanListInfo.at(0), true); + //处理列表 未连接 + for (int i = 1; i < wlanListInfo.length(); i++) { + qDebug() << "[NetConnect]initNetListFromDevice " << deviceName << " deacitved lan " << wlanListInfo.at(i); + addLanItem(deviceFrameMap[deviceName], deviceName, wlanListInfo.at(i), false); + } + } + } + return; +} + +//初始化时添加一个项 不考虑顺序 +void NetConnect::addLanItem(ItemFrame *frame, QString devName, QStringList infoList, bool isActived) +{ + if (frame == nullptr) { + return; + } + if (infoList.size() == 1) { + return; + } + + LanItem * lanItem = new LanItem(pluginWidget); + QString iconPath = KLanSymbolic; + if (isActived) { + lanItem->statusLabel->setText(tr("connected")); + } else { + lanItem->statusLabel->setText(""); + } + QIcon searchIcon = QIcon::fromTheme(iconPath); +// if (iconPath != KLanSymbolic && iconPath != NoNetSymbolic) { +// lanItem->iconLabel->setProperty("useIconHighlightEffect", 0x10); +// } + lanItem->iconLabel->setPixmap(searchIcon.pixmap(searchIcon.actualSize(QSize(24, 24)))); + lanItem->titileLabel->setText(infoList.at(0)); + + lanItem->uuid = infoList.at(1); + lanItem->dbusPath = infoList.at(2); + + connect(lanItem->infoLabel, &InfoButton::clicked, this, [=]{ + // open landetail page + if (!m_interface->isValid()) { + return; + } + qDebug() << "[NetConnect]call showPropertyWidget" << __LINE__; + m_interface->call(QStringLiteral("showPropertyWidget"), devName, infoList.at(1)); + qDebug() << "[NetConnect]call showPropertyWidget respond" << __LINE__; + }); + + lanItem->isAcitve = isActived; + + connect(lanItem, &QPushButton::clicked, this, [=] { + if (lanItem->isAcitve || lanItem->loading) { + deActiveConnect(lanItem->uuid, devName, WIRED_TYPE); + } else { + activeConnect(lanItem->uuid, devName, WIRED_TYPE); + } + }); + + //记录到deviceFrame的itemMap中 + deviceFrameMap[devName]->itemMap.insert(infoList.at(1), lanItem); + qDebug()<<"insert " << infoList.at(1) << " to " << devName << " list"; + frame->lanItemLayout->addWidget(lanItem); +} + +//增加设备 +void NetConnect::addDeviceFrame(QString devName) +{ + qDebug() << "[NetConnect]addDeviceFrame " << devName; + + qDebug() << "[NetConnect]call getDeviceListAndEnabled" << __LINE__; + QDBusMessage result = m_interface->call(QStringLiteral("getDeviceListAndEnabled"),0); + qDebug() << "[NetConnect]call getDeviceListAndEnabled Respond" << __LINE__; + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "[NetConnect]getWiredDeviceList error:" << result.errorMessage(); + return; + } + auto dbusArg = result.arguments().at(0).value(); + QMap map; + dbusArg >> map; + + bool enable = true; + if (map.contains(devName)) { + enable = map[devName]; + } + + ItemFrame *itemFrame = new ItemFrame(devName, pluginWidget); + ui->availableLayout->addWidget(itemFrame); + itemFrame->deviceFrame->deviceLabel->setText(tr("card")+/*QString("%1").arg(count)+*/":"+devName); + itemFrame->deviceFrame->deviceSwitch->setChecked(enable); + if (enable) { + itemFrame->lanItemFrame->show(); + itemFrame->deviceFrame->dropDownLabel->show(); + } else { + itemFrame->lanItemFrame->hide(); + itemFrame->deviceFrame->dropDownLabel->hide(); + itemFrame->deviceFrame->dropDownLabel->setDropDownStatus(false); + } + deviceFrameMap.insert(devName, itemFrame); + qDebug() << "[NetConnect]deviceFrameMap insert" << devName; + + connect(itemFrame->deviceFrame->deviceSwitch, &SwitchButton::checkedChanged, this, [=] (bool checked) { + qDebug() << "[NetConnect]call setDeviceEnable" << devName << checked << __LINE__; + m_interface->call(QStringLiteral("setDeviceEnable"), devName, checked); + qDebug() << "[NetConnect]call setDeviceEnable Respond" << __LINE__; + if (checked) { + qDebug() << "[NetConnect]set " << devName << "status" << true; + itemFrame->lanItemFrame->show(); + itemFrame->deviceFrame->dropDownLabel->show(); + itemFrame->deviceFrame->dropDownLabel->setDropDownStatus(true); + deviceStatusMap[devName] = true; + } else { + qDebug() << "[NetConnect]set " << devName << "status" << false; + itemFrame->lanItemFrame->hide(); + itemFrame->deviceFrame->dropDownLabel->hide(); + deviceStatusMap[devName] = false; + } + }); + + connect(itemFrame->addLanWidget, &AddNetBtn::clicked, this, [=](){ + if (m_interface->isValid()) { + qDebug() << "[NetConnect]call showCreateWiredConnectWidget" << devName << __LINE__; + m_interface->call(QStringLiteral("showCreateWiredConnectWidget"), devName); + qDebug() << "[NetConnect]call setDeviceEnable Respond" << __LINE__; + } + }); +} + +//减少设备 +void NetConnect::removeDeviceFrame(QString devName) +{ + qDebug() << "[NetConnect]removeDeviceFrame " << devName; + if (deviceFrameMap.contains(devName)) { + ItemFrame *item = deviceFrameMap[devName]; + if (item->lanItemFrame->layout() != NULL) { + QLayoutItem* layoutItem; + while ((layoutItem = item->lanItemFrame->layout()->takeAt(0)) != NULL) { + delete layoutItem->widget(); + delete layoutItem; + layoutItem = nullptr; + } + item->itemMap.clear(); + } + delete item; + item = nullptr; + deviceFrameMap.remove(devName); + qDebug() << "[NetConnect]deviceFrameMap remove" << devName; + } +} + +//device add or remove================================= +void NetConnect::onDeviceStatusChanged() +{ + qDebug()<<"[NetConnect]onDeviceStatusChanged"; + QEventLoop eventloop; + QTimer::singleShot(300, &eventloop, SLOT(quit())); + eventloop.exec(); + QStringList list; + QMap map; + getDeviceStatusMap(map); + list = map.keys(); + + QStringList removeList; + QMap addMap; + + //remove的设备 + for (int i = 0; i< deviceStatusMap.keys().size(); ++i) { + if (!list.contains(deviceStatusMap.keys().at(i))) { + qDebug() << "[NetConnect]onDeviceStatusChanged " << deviceStatusMap.keys().at(i) << "was removed"; + removeList << deviceStatusMap.keys().at(i); + } + } + + //add的设备 + for (int i = 0; i< list.size(); ++i) { + if (!deviceStatusMap.keys().contains(list.at(i))) { + qDebug() << "[NetConnect]onDeviceStatusChanged " << list.at(i) << "was add, init status" << map[list.at(i)]; + addMap.insert(list.at(i),map[list.at(i)]); + } + } + + for (int i = 0; i < removeList.size(); ++i) { + removeDeviceFrame(removeList.at(i)); + } + + QStringList addList = addMap.keys(); + for (int i = 0; i < addList.size(); ++i) { + qDebug() << "add a device " << addList.at(i) << "status" << map[addList.at(i)]; + addDeviceFrame(addList.at(i)); + initNetListFromDevice(addList.at(i)); + } + deviceStatusMap = map; + if (deviceStatusMap.isEmpty()) { + wiredSwitch->setDisabledFlag(true); + wiredSwitch->setChecked(false); + } else { + wiredSwitch->setDisabledFlag(false); + setSwitchStatus(); + } + +} + +void NetConnect::onDeviceNameChanged(QString oldName, QString newName, int type) +{ + if (WIRED_TYPE != type || !deviceFrameMap.contains(oldName) || !deviceStatusMap.contains(oldName)) { + qDebug() << "[NetConnect]onDeviceNameChanged no such device " << oldName; + return; + } + + if (deviceFrameMap.contains(newName) && deviceStatusMap.contains(newName)) { + qDebug() << "[NetConnect]onDeviceNameChanged already has device " << newName; + return; + } + + qDebug() << "[NetConnect]onDeviceNameChanged " << oldName << "change to" << newName; + + //shan chu chong jian + removeDeviceFrame(oldName); + removeDeviceFrame(newName); + + getDeviceStatusMap(deviceStatusMap); + if (deviceStatusMap.contains(newName)) { + addDeviceFrame(newName); + initNetListFromDevice(newName); + } +} + +//wifi add=============================================================== +void NetConnect::onLanAdd(QString deviceName, QStringList lanInfo) +{ + qDebug()<<"[NetConnect]onLanAdd "<< deviceName << " " << lanInfo; + + if (!deviceName.isEmpty() && !deviceStatusMap.contains(deviceName)) { + return; + } + + QMap::iterator iter; + for (iter = deviceFrameMap.begin(); iter != deviceFrameMap.end(); iter++) { + if (deviceName.isEmpty()) { + qDebug() << "[NetConnect]onLanAdd every list" << iter.key(); + addOneLanFrame(iter.value(), iter.key(), lanInfo); + } else if (deviceName == iter.key()) { + qDebug() << "[NetConnect]onLanAdd "<< deviceName; + addOneLanFrame(iter.value(), deviceName, lanInfo); + break; + } + } +} + +//wifi remove ============================================================= +void NetConnect::onLanRemove(QString lanPath) +{ + //开关已关闭 忽略 +// if (!wifiSwtch->isChecked()) { +// qDebug() << "[NetConnect]recieve network remove,but wireless switch is off"; +// return; +// } + + qDebug()<<"[NetConnect]lan remove " << "dbus path:" << lanPath; + QMap::iterator iter; + for (iter = deviceFrameMap.begin(); iter != deviceFrameMap.end(); iter++) { + QMap::iterator itemIter; + for (itemIter = iter.value()->itemMap.begin(); itemIter != iter.value()->itemMap.end(); itemIter++) { + if (itemIter.value()->dbusPath == lanPath) { + qDebug()<<"[NetConnect]lan remove " << lanPath << " find in " << itemIter.value()->titileLabel->text(); + QString key = itemIter.key(); + iter.value()->lanItemLayout->removeWidget(itemIter.value()); + delete itemIter.value(); + iter.value()->itemMap.remove(key); + break; + } + } + } +} + +//增加一项 +void NetConnect::addOneLanFrame(ItemFrame *frame, QString deviceName, QStringList infoList) +{ + if (nullptr == frame) { + return; + } + + if (frame->itemMap.contains(infoList.at(1))) { + qDebug() << "[NetConnect]Already exist a lan " << infoList.at(1) << " in " << deviceName; + return; + } + + qDebug() << "[NetConnect]addOneLanFrame" << deviceName << infoList.at(0); + QString connName = infoList.at(0); + QString connUuid = infoList.at(1); + QString connDbusPath = infoList.at(2); + LanItem * lanItem = new LanItem(pluginWidget); + + QString iconPath; + iconPath = KLanSymbolic; + lanItem->statusLabel->setText(""); + + QIcon searchIcon = QIcon::fromTheme(iconPath); +// if (iconPath != KLanSymbolic && iconPath != NoNetSymbolic) { +// lanItem->iconLabel->setProperty("useIconHighlightEffect", 0x10); +// } + lanItem->iconLabel->setPixmap(searchIcon.pixmap(searchIcon.actualSize(QSize(24, 24)))); + lanItem->titileLabel->setText(connName); + + lanItem->uuid = connUuid; + lanItem->dbusPath = connDbusPath; + + connect(lanItem->infoLabel, &InfoButton::clicked, this, [=]{ + // open landetail page + if (!m_interface->isValid()) { + return; + } + qDebug() << "[NetConnect]call showPropertyWidget" << deviceName << connUuid << __LINE__; + m_interface->call(QStringLiteral("showPropertyWidget"), deviceName, connUuid); + qDebug() << "[NetConnect]call showPropertyWidget respond" << __LINE__; + }); + + lanItem->isAcitve = false; + + connect(lanItem, &QPushButton::clicked, this, [=] { + if (lanItem->isAcitve || lanItem->loading) { + deActiveConnect(lanItem->uuid, deviceName, WIRED_TYPE); + } else { + activeConnect(lanItem->uuid, deviceName, WIRED_TYPE); + } + }); + + //记录到deviceFrame的itemMap中 + deviceFrameMap[deviceName]->itemMap.insert(connUuid, lanItem); + int index = getInsertPos(connName, deviceName); + qDebug()<<"[NetConnect]addOneLanFrame " << connName << " to " << deviceName << " list at pos:" << index; + frame->lanItemLayout->insertWidget(index, lanItem); +} + +void NetConnect::removeOneLanFrame(ItemFrame *frame, QString deviceName, QString uuid) +{ + if (nullptr == frame) { + return; + } + + if (!frame->itemMap.contains(uuid)) { + qDebug() << "[NetConnect]not exist a lan " << uuid << " in " << deviceName; + return; + } + + qDebug()<<"[NetConnect]removeOneLanFrame " << uuid << " find in " << deviceName; + + frame->lanItemLayout->removeWidget(frame->itemMap[uuid]); + delete frame->itemMap[uuid]; + frame->itemMap.remove(uuid); +} + +//activeconnect status change +void NetConnect::onActiveConnectionChanged(QString deviceName, QString uuid, int status) +{ + if (uuid.isEmpty()) { + qDebug() << "[NetConnect]onActiveConnectionChanged but uuid is empty"; + return; + } + qDebug() << "[NetConnect]onActiveConnectionChanged " << deviceName << uuid << status; + LanItem * item= nullptr; + if (deviceName.isEmpty()) { + if (status != DEACTIVATED) { + return; + } + //断开时 设备为空 说明此有线未指定设备 添加到所有列表中 + QStringList infoList; + QMap::iterator iters; + for (iters = deviceFrameMap.begin(); iters != deviceFrameMap.end(); iters++) { + if (iters.value()->itemMap.contains(uuid)) { + item = iters.value()->itemMap[uuid]; + infoList << item->titileLabel->text() << item->uuid << item->dbusPath; + //为断开则重新插入 + int index = getInsertPos(item->titileLabel->text(), iters.key()); + qDebug() << "[NetConnect]reinsert" << item->titileLabel->text() << "pos" << index << "in" << iters.key() << "because status changes to deactive"; + deviceFrameMap[iters.key()]->lanItemLayout->removeWidget(item); + deviceFrameMap[iters.key()]->lanItemLayout->insertWidget(index,item); + itemActiveConnectionStatusChanged(item, status); + } + } + //添加到所有列表中 + if (!infoList.isEmpty()) { + QMap::iterator iter; + for (iter = deviceFrameMap.begin(); iter != deviceFrameMap.end(); iter++) { + if (!iter.value()->itemMap.contains(uuid)) { + addOneLanFrame(iter.value(), iter.key(), infoList); + } + } + } + } else { + if (deviceFrameMap.contains(deviceName)) { + if (deviceFrameMap[deviceName]->itemMap.contains(uuid)) { + item = deviceFrameMap[deviceName]->itemMap[uuid]; + if (status == ACTIVATED) { + //为已连接则放到第一个 + deviceFrameMap[deviceName]->lanItemLayout->removeWidget(item); + deviceFrameMap[deviceName]->lanItemLayout->insertWidget(0,item); + } else if (status == DEACTIVATED) { + //为断开则重新插入 + int index = getInsertPos(item->titileLabel->text(), deviceName); + qDebug() << "[NetConnect]reinsert" << item->titileLabel->text() << "pos" << index << "in" << deviceName << "because status changes to deactive"; + deviceFrameMap[deviceName]->lanItemLayout->removeWidget(item); + deviceFrameMap[deviceName]->lanItemLayout->insertWidget(index,item); + } + itemActiveConnectionStatusChanged(item, status); + } + } else { + if (status == ACTIVATED || status == DEACTIVATED) { + //虚拟网卡处理 + QMap::iterator iters; + for (iters = deviceFrameMap.begin(); iters != deviceFrameMap.end(); iters++) { + if (iters.value()->itemMap.contains(uuid)) { + removeOneLanFrame(iters.value(), iters.key(), uuid); + } + } + } + } + } +} + +void NetConnect::itemActiveConnectionStatusChanged(LanItem *item, int status) +{ +// QString iconPath = NoNetSymbolic; + if (status == ACTIVATING) { + item->startLoading(); + } else if (status == ACTIVATED) { + item->stopLoading(); +// iconPath = KLanSymbolic; + item->statusLabel->clear(); + item->statusLabel->setMinimumSize(36,36); + item->statusLabel->setMaximumSize(16777215,16777215); + item->statusLabel->setText(tr("connected")); + item->isAcitve = true; + } else if (status == DEACTIVATING) { + item->startLoading(); + } else { + item->stopLoading(); + item->statusLabel->setMinimumSize(36,36); + item->statusLabel->setMaximumSize(16777215,16777215); + item->statusLabel->clear(); + item->isAcitve = false; + } + +// QIcon searchIcon = QIcon::fromTheme(iconPath); +// item->iconLabel->setPixmap(searchIcon.pixmap(searchIcon.actualSize(QSize(24, 24)))); +} + +int NetConnect::getInsertPos(QString connName, QString deviceName) +{ + qDebug() << "[NetConnect]getInsertPos" << connName << deviceName; + int index = 0; + if(!m_interface->isValid()) { + index = 0; + } else { + qDebug() << "[NetConnect]call getWiredList" << __LINE__; + QDBusMessage result = m_interface->call(QStringLiteral("getWiredList")); + qDebug() << "[NetConnect]call getWiredList respond" << __LINE__; + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "getWiredList error:" << result.errorMessage(); + return 0; + } + auto dbusArg = result.arguments().at(0).value(); + QMap> variantList; + dbusArg >> variantList; + if (!variantList.contains(deviceName)) { + qDebug() << "[NetConnect] getInsertPos but " << deviceName << "not exist"; + return 0; + } + for (int i = 0; i < variantList[deviceName].size(); ++i ) { + if (variantList[deviceName].at(i).at(0) == connName) { + qDebug() << "pos in kylin-nm is " << i; + index = i; + break; + } + } + if (variantList[deviceName].at(0).size() == 1) { + index--; + } + } + return index; +} diff --git a/plugins/netconnect/netconnect.h b/plugins/netconnect/netconnect.h new file mode 100644 index 00000000..2126c399 --- /dev/null +++ b/plugins/netconnect/netconnect.h @@ -0,0 +1,156 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. + * + * 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 NETCONNECT_H +#define NETCONNECT_H + + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "interface.h" +#include "addbtn.h" +#include "fixlabel.h" +#include "switchbutton.h" +#include "hoverbtn.h" +#include "lanitem.h" +#include "deviceframe.h" +#include "itemframe.h" + +enum { + DISCONNECTED, + NOINTERNET, + CONNECTED +}; + +namespace Ui { +class NetConnect; +} + +class NetConnect : public QObject, CommonInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.ukcc.CommonInterface") + Q_INTERFACES(CommonInterface) + +public: + NetConnect(); + ~NetConnect(); + + QString plugini18nName() Q_DECL_OVERRIDE; + int pluginTypes() Q_DECL_OVERRIDE; + QWidget * pluginUi() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; + bool isShowOnHomePage() const Q_DECL_OVERRIDE; + QIcon icon() const Q_DECL_OVERRIDE; + bool isEnable() const Q_DECL_OVERRIDE; + QString translationPath() const Q_DECL_OVERRIDE; +private: + void initSearchText(); + void initComponent(); + void runExternalApp(); + + void showDesktopNotify(const QString &message); + + + //开关相关 + void setSwitchStatus(); + void hideLayout(QVBoxLayout * layout); + void showLayout(QVBoxLayout * layout); + + int getInsertPos(QString connName, QString deviceName); + + + void deleteOneLan(QString ssid); + void activeConnect(QString ssid, QString deviceName, int type); + void deActiveConnect(QString ssid, QString deviceName, int type); + + //获取设备列表 + void getDeviceStatusMap(QMap &map); + void initNet(); + void initNetListFromDevice(QString deviceName); + //处理列表增加 + void addLanItem(ItemFrame *frame, QString devName, QStringList infoList, bool isActived); + //增加设备 + void addDeviceFrame(QString devName); + //减少设备 + void removeDeviceFrame(QString devName); + //增加一项 + void addOneLanFrame(ItemFrame *frame, QString devName, QStringList infoList); + //减少一项 + void removeOneLanFrame(ItemFrame *frame, QString deviceName, QString uuid); + + //单个lan连接状态变化 + void itemActiveConnectionStatusChanged(LanItem *item, int status); + +protected: + bool eventFilter(QObject *w,QEvent *e); + +private: + Ui::NetConnect *ui; + + QString pluginName; + int pluginType; + QWidget *pluginWidget; + + QDBusInterface *m_interface = nullptr; + SwitchButton *wiredSwitch; + + bool mFirstLoad; + QGSettings *m_switchGsettings; + + QMap deviceStatusMap; + QMap deviceFrameMap; + +private slots: + void updateLanInfo(QString deviceName, QStringList lanInfo); + + void onLanAdd(QString deviceName, QStringList lanInfo); + void onLanRemove(QString dbusPath); + + void onActiveConnectionChanged(QString deviceName, QString uuid, int status); + + void onDeviceStatusChanged(); + void onDeviceNameChanged(QString, QString, int); +}; + +Q_DECLARE_METATYPE(QList); + +#endif // NETCONNECT_H diff --git a/plugins/netconnect/netconnect.pro b/plugins/netconnect/netconnect.pro new file mode 100644 index 00000000..c6245ada --- /dev/null +++ b/plugins/netconnect/netconnect.pro @@ -0,0 +1,53 @@ +QT += widgets network dbus gui core +TEMPLATE = lib +CONFIG += plugin + +include(../component/drownlabel.pri) + +TARGET = $$qtLibraryTarget(netconnect) +DESTDIR = ../.. +target.path = $$[QT_INSTALL_LIBS]/ukui-control-center +trans.files = translations/* +trans.path = /usr/share/kylin-nm/netconnect/ + +INCLUDEPATH += \ + $$PROJECT_COMPONENTSOURCE \ + $$PROJECT_ROOTDIR \ + /usr/include/ukcc/interface \ + /usr/include/ukcc/widgets + +LIBS += -L$$[QT_INSTALL_LIBS] -lgsettings-qt -lukcc + +CONFIG += c++11 \ + link_pkgconfig \ + +PKGCONFIG += gsettings-qt \ + +#DEFINES += QT_DEPRECATED_WARNINGS + +SOURCES += \ + addnetbtn.cpp \ + deviceframe.cpp \ +# drownlabel.cpp \ + itemframe.cpp \ + lanitem.cpp \ + netconnect.cpp + +HEADERS += \ + addnetbtn.h \ + deviceframe.h \ +# drownlabel.h \ + itemframe.h \ + lanitem.h \ + netconnect.h + +FORMS += \ + netconnect.ui + +INSTALLS += target \ + trans + +TRANSLATIONS += \ + translations/zh_CN.ts \ + translations/tr.ts \ + translations/bo.ts diff --git a/plugins/netconnect/netconnect.ui b/plugins/netconnect/netconnect.ui new file mode 100644 index 00000000..4c4e2267 --- /dev/null +++ b/plugins/netconnect/netconnect.ui @@ -0,0 +1,244 @@ + + + NetConnect + + + + 0 + 0 + 885 + 700 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + NetConnect + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + Wired Network + + + true + + + + + + + 1 + + + 0 + + + + + + 0 + 60 + + + + + 16777215 + 50 + + + + QFrame::Box + + + + 18 + + + 0 + + + 9 + + + 0 + + + + + 0 + + + 8 + + + + + + 118 + 0 + + + + open + + + + + + + Qt::Horizontal + + + + 523 + 20 + + + + + + + + + + + + + + + 1 + + + 0 + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 1 + + + + + + + + + + + + + + + + 120 + 36 + + + + + 16777215 + 36 + + + + Advanced settings + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + TitleLabel + QLabel +
titlelabel.h
+
+
+ + +
diff --git a/plugins/netconnect/translations/bo.qm b/plugins/netconnect/translations/bo.qm new file mode 100644 index 00000000..be651eed --- /dev/null +++ b/plugins/netconnect/translations/bo.qm @@ -0,0 +1 @@ + + + + + AddNetBtn + + + Add WiredNetork + + + + + NetConnect + + + + Wired Network + + + + + + open + + /netconnect/open + + + + + Advanced settings + + /netconnect/Advanced settings" + + + + ukui control center + + + + + ukui control center desktop message + + + + + WiredConnect + + + + + No ethernet device avaliable + + + + + + connected + + + + + card + + + + diff --git a/plugins/netconnect/translations/tr.qm b/plugins/netconnect/translations/tr.qm new file mode 100644 index 00000000..be651eed --- /dev/null +++ b/plugins/netconnect/translations/tr.qm @@ -0,0 +1 @@ + + + + + AddNetBtn + + + Add WiredNetork + + + + + NetConnect + + + + Wired Network + + + + + + open + + /netconnect/open + + + + + Advanced settings + + /netconnect/Advanced settings" + + + + ukui control center + + + + + ukui control center desktop message + + + + + WiredConnect + + + + + No ethernet device avaliable + + + + + + connected + + + + + card + + + + diff --git a/plugins/netconnect/translations/zh_CN.qm b/plugins/netconnect/translations/zh_CN.qm new file mode 100644 index 00000000..97f6e862 Binary files /dev/null and b/plugins/netconnect/translations/zh_CN.qm differ diff --git a/plugins/netconnect/translations/zh_CN.ts b/plugins/netconnect/translations/zh_CN.ts new file mode 100644 index 00000000..0424b7b0 --- /dev/null +++ b/plugins/netconnect/translations/zh_CN.ts @@ -0,0 +1,66 @@ + + + + + AddNetBtn + + + Add WiredNetork + 添加有线网络 + + + + NetConnect + + + + Wired Network + 有线网络 + + + + + open + 开启 + /netconnect/open + + + + + Advanced settings + 高级设置 + /netconnect/Advanced settings" + + + + ukui control center + 控制面板 + + + + ukui control center desktop message + 控制面板桌面通知 + + + + WiredConnect + 有线网络 + + + + No ethernet device avaliable + 未检测到有线设备 + + + + + connected + 已连接 + + + + card + 网卡 + + + diff --git a/plugins/plugin.pro b/plugins/plugin.pro new file mode 100644 index 00000000..f370e3be --- /dev/null +++ b/plugins/plugin.pro @@ -0,0 +1,5 @@ +TEMPLATE = subdirs +SUBDIRS = \ + netconnect \ + wlanconnect \ + mobilehotspot diff --git a/plugins/wlanconnect/deviceframe.cpp b/plugins/wlanconnect/deviceframe.cpp new file mode 100644 index 00000000..a616d65f --- /dev/null +++ b/plugins/wlanconnect/deviceframe.cpp @@ -0,0 +1,48 @@ +#include "deviceframe.h" +#include + +#define LAYOUT_MARGINS 18,0,8,0 +#define FRAME_HEIGHT 58 +#define LAYOUT_SPACING 16 +#define RADIUS 6.0 + +DeviceFrame::DeviceFrame(QString devName, QWidget *parent) : QFrame(parent) +{ + this->setFrameShape(QFrame::Box); + this->setFixedHeight(FRAME_HEIGHT); + QHBoxLayout *deviceLayout = new QHBoxLayout(this); + deviceLayout->setContentsMargins(LAYOUT_MARGINS); + setLayout(deviceLayout); + deviceLayout->setSpacing(LAYOUT_SPACING); + + deviceLabel = new QLabel(this); + dropDownLabel = new DrownLabel(devName, this); + + deviceLayout->addWidget(deviceLabel); + deviceLayout->addStretch(); + deviceLayout->addWidget(dropDownLabel); +} + +DeviceFrame::~DeviceFrame() +{ + +} + +void DeviceFrame::paintEvent(QPaintEvent *event) +{ + QPalette pal = this->palette(); + + QPainter painter(this); + painter.setRenderHint(QPainter:: Antialiasing, true); //设置渲染,启动反锯齿 + painter.setPen(Qt::NoPen); + painter.setBrush(pal.color(QPalette::Base)); + + QRect rect = this->rect(); + QPainterPath path; + path.addRoundedRect (rect, RADIUS, RADIUS); + QRect temp_rect(rect.left(), rect.top() + rect.height()/2, rect.width(), rect.height()/2); + path.addRect(temp_rect); + painter.drawPath(path); + QFrame::paintEvent(event); +} + diff --git a/plugins/wlanconnect/deviceframe.h b/plugins/wlanconnect/deviceframe.h new file mode 100644 index 00000000..f70eda47 --- /dev/null +++ b/plugins/wlanconnect/deviceframe.h @@ -0,0 +1,30 @@ +#ifndef DEVICEFRAME_H +#define DEVICEFRAME_H +#include +#include +#include +#include +#include +#include +#include "../component/DrownLabel/drownlabel.h" + +class DeviceFrame : public QFrame +{ + +public: + DeviceFrame(QString devName, QWidget *parent = nullptr); + ~DeviceFrame(); +public: + //仅设备名称+下拉label + QLabel * deviceLabel = nullptr; + DrownLabel *dropDownLabel = nullptr; + +protected: + void paintEvent(QPaintEvent *event); + +private: + int frameSize; + +}; + +#endif // DEVICEFRAME_H diff --git a/plugins/wlanconnect/itemframe.cpp b/plugins/wlanconnect/itemframe.cpp new file mode 100644 index 00000000..572de528 --- /dev/null +++ b/plugins/wlanconnect/itemframe.cpp @@ -0,0 +1,61 @@ +#include "itemframe.h" +#include + +#define LAYOUT_MARGINS 0,0,0,0 +#define MAIN_LAYOUT_MARGINS 0,0,0,0 +ItemFrame::ItemFrame(QString devName, QWidget *parent) +{ + deviceLanLayout = new QVBoxLayout(this); + deviceLanLayout->setContentsMargins(MAIN_LAYOUT_MARGINS); + lanItemFrame = new QFrame(this); + lanItemFrame->setFrameShape(QFrame::Shape::NoFrame); + lanItemFrame->setContentsMargins(LAYOUT_MARGINS); + + lanItemLayout = new QVBoxLayout(this); + lanItemLayout->setContentsMargins(LAYOUT_MARGINS); + lanItemLayout->setSpacing(1); + + deviceLanLayout->setSpacing(1); + setLayout(deviceLanLayout); + lanItemFrame->setLayout(lanItemLayout); + + deviceFrame = new DeviceFrame(devName, this); + deviceLanLayout->addWidget(deviceFrame); + deviceLanLayout->addWidget(lanItemFrame); + + //下拉按钮 + connect(deviceFrame->dropDownLabel, &DrownLabel::labelClicked, this, &ItemFrame::onDrownLabelClicked); +} + +ItemFrame::~ItemFrame() +{ + +} + +void ItemFrame::onDrownLabelClicked() +{ + if (!deviceFrame->dropDownLabel->isChecked) { + lanItemFrame->show(); + deviceFrame->dropDownLabel->setDropDownStatus(true); + } else { + lanItemFrame->hide(); + deviceFrame->dropDownLabel->setDropDownStatus(false); + } +} + +void ItemFrame::filletStyleChange() +{ + if (lanItemLayout->isEmpty()) { + return; + } + + for (int i = 0; i < lanItemLayout->count(); ++i) { + QLayoutItem *it = lanItemLayout->itemAt(i); + WlanItem *itemFrame = (WlanItem*)(it->widget()); + if (i != lanItemLayout->count()-1) { + itemFrame->setHalfFillet(false); + } else { + itemFrame->setHalfFillet(true); + } + } +} diff --git a/plugins/wlanconnect/itemframe.h b/plugins/wlanconnect/itemframe.h new file mode 100644 index 00000000..02e78876 --- /dev/null +++ b/plugins/wlanconnect/itemframe.h @@ -0,0 +1,33 @@ +#ifndef ITEMFRAME_H +#define ITEMFRAME_H +#include +#include +#include "deviceframe.h" +#include "wlanitem.h" + +class ItemFrame : public QFrame +{ + Q_OBJECT +public: + ItemFrame(QString devName, QWidget *parent = nullptr); + ~ItemFrame(); + //单设备整体layout + QVBoxLayout * deviceLanLayout = nullptr; + //单设备名称+下拉按钮Frame + DeviceFrame * deviceFrame = nullptr; + //单设备列表Frame + QFrame * lanItemFrame = nullptr; + //单设备列表layout + QVBoxLayout * lanItemLayout = nullptr; + //单设备item列表 + QMap itemMap; + //已激活uuid + QString uuid = ""; + + void filletStyleChange(); + +private slots: + void onDrownLabelClicked(); +}; + +#endif // ITEMFRAME_H diff --git a/plugins/wlanconnect/translations/bo.qm b/plugins/wlanconnect/translations/bo.qm new file mode 100644 index 00000000..be651eed --- /dev/null +++ b/plugins/wlanconnect/translations/bo.qm @@ -0,0 +1 @@ + + + + + WlanConnect + + + + WlanConnect + + + + + + WLAN + + + + + + open + + /wlanconnect/open + + + + + Advanced settings + + /wlanconnect/Advanced settings" + + + + ukui control center + + + + + ukui control center desktop message + + + + + No wireless network card detected + + + + + + + connected + + + + + card + + + + diff --git a/plugins/wlanconnect/translations/tr.qm b/plugins/wlanconnect/translations/tr.qm new file mode 100644 index 00000000..be651eed --- /dev/null +++ b/plugins/wlanconnect/translations/tr.qm @@ -0,0 +1 @@ + + + + + WlanConnect + + + + WlanConnect + + + + + + WLAN + + + + + + open + + /wlanconnect/open + + + + + Advanced settings + + /wlanconnect/Advanced settings" + + + + ukui control center + + + + + ukui control center desktop message + + + + + No wireless network card detected + + + + + + + connected + + + + + card + + + + diff --git a/plugins/wlanconnect/translations/zh_CN.qm b/plugins/wlanconnect/translations/zh_CN.qm new file mode 100644 index 00000000..7d9a0216 Binary files /dev/null and b/plugins/wlanconnect/translations/zh_CN.qm differ diff --git a/plugins/wlanconnect/translations/zh_CN.ts b/plugins/wlanconnect/translations/zh_CN.ts new file mode 100644 index 00000000..a96e660b --- /dev/null +++ b/plugins/wlanconnect/translations/zh_CN.ts @@ -0,0 +1,60 @@ + + + + + WlanConnect + + + + WlanConnect + 无线局域网 + + + + + WLAN + 无线局域网 + + + + + open + 开启 + /wlanconnect/open + + + + + Advanced settings + 高级设置 + /wlanconnect/Advanced settings" + + + + ukui control center + 控制面板 + + + + ukui control center desktop message + 控制面板桌面通知 + + + + No wireless network card detected + 未检测到无线网卡 + + + + + + connected + 已连接 + + + + card + 网卡 + + + diff --git a/plugins/wlanconnect/wlanconnect.cpp b/plugins/wlanconnect/wlanconnect.cpp new file mode 100644 index 00000000..7c415179 --- /dev/null +++ b/plugins/wlanconnect/wlanconnect.cpp @@ -0,0 +1,1007 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. + * + * 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 "wlanconnect.h" +#include "ui_wlanconnect.h" + +#include +#include +#include +#include +#include +#include +#include + +#define WIRELESS_TYPE 1 + +#define SCANTIMER 20 * 1000 +#define UPDATETIMER 5 * 1000 + +#define SPACING 8 + +const QString WIRELESS_SWITCH = "wirelessswitch"; +const QByteArray GSETTINGS_SCHEMA = "org.ukui.kylin-nm.switch"; + +const QString KWifiSymbolic = "network-wireless-signal-excellent"; +const QString KWifiLockSymbolic = "network-wireless-secure-signal-excellent"; +const QString KWifiGood = "network-wireless-signal-good"; +const QString KWifiLockGood = "network-wireless-secure-signal-good"; +const QString KWifiOK = "network-wireless-signal-ok"; +const QString KWifiLockOK = "network-wireless-secure-signal-ok"; +const QString KWifiLow = "network-wireless-signal-low"; +const QString KWifiLockLow = "network-wireless-secure-signal-low"; +const QString KWifiNone = "network-wireless-signal-none"; +const QString KWifiLockNone = "network-wireless-secure-signal-none"; + +const QString KLanSymbolic = ":/img/plugins/netconnect/eth.svg"; +const QString NoNetSymbolic = ":/img/plugins/netconnect/nonet.svg"; + +const QString KApSymbolic = "network-wireless-hotspot-symbolic"; + +const QString IsApConnection = "1"; + + +#define ACTIVATING 1 +#define ACTIVATED 2 +#define DEACTIVATING 3 +#define DEACTIVATED 4 + +#define NO_MARGINS 0,0,0,0 +#define MAIN_LAYOUT_MARGINS 0,0,0,8 + +bool intThan(int sign1, int sign2) +{ + return sign1 < sign2; +} + +void WlanConnect::showDesktopNotify(const QString &message) +{ + QDBusInterface iface("org.freedesktop.Notifications", + "/org/freedesktop/Notifications", + "org.freedesktop.Notifications", + QDBusConnection::sessionBus()); + QList args; + args<<(tr("ukui control center")) + <<((unsigned int) 0) + <load("/usr/share/kylin-nm/wlanconnect/" + QLocale::system().name()); + QApplication::installTranslator(translator); + + pluginName = tr("WlanConnect"); + pluginType = NETWORK; +} + +WlanConnect::~WlanConnect() +{ + if (!m_firstLoad) { + delete ui; + ui = nullptr; + } + delete m_interface; + delete m_switchGsettings; +} + +QString WlanConnect::plugini18nName() { + return pluginName; +} + +int WlanConnect::pluginTypes() { + return pluginType; +} + +QWidget *WlanConnect::pluginUi() { + if (m_firstLoad) { + m_firstLoad = false; + + ui = new Ui::WlanConnect; + pluginWidget = new QWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(pluginWidget); + qDBusRegisterMetaType>(); + m_interface = new QDBusInterface("com.kylin.network", "/com/kylin/network", + "com.kylin.network", + QDBusConnection::sessionBus()); + if(!m_interface->isValid()) { + qWarning() << qPrintable(QDBusConnection::sessionBus().lastError().message()); + } + initComponent(); + } + return pluginWidget; +} + +const QString WlanConnect::name() const { + + return QStringLiteral("wlanconnect"); +} + +bool WlanConnect::isEnable() const +{ + return true; +} + + +bool WlanConnect::isShowOnHomePage() const +{ + return true; +} + +QIcon WlanConnect::icon() const +{ + return QIcon(); +} + +QString WlanConnect::translationPath() const +{ + return "/usr/share/kylin-nm/wlanconnect/%1.ts"; +} + +void WlanConnect::initSearchText() { + //~ contents_path /wlanconnect/Advanced settings" + ui->detailBtn->setText(tr("Advanced settings")); + ui->titleLabel->setText(tr("WLAN")); + //~ contents_path /wlanconnect/open + ui->openLabel->setText(tr("open")); +} + +bool WlanConnect::eventFilter(QObject *w, QEvent *e) { + if (e->type() == QEvent::Enter) { + if (w->findChild()) + w->findChild()->setStyleSheet("QWidget{background: palette(button);border-radius:4px;}"); + } else if (e->type() == QEvent::Leave) { + if (w->findChild()) + w->findChild()->setStyleSheet("QWidget{background: palette(base);border-radius:4px;}"); + } + return QObject::eventFilter(w,e); +} + +void WlanConnect::initComponent() { + m_wifiSwitch = new SwitchButton(pluginWidget); + ui->openWIifLayout->addWidget(m_wifiSwitch); + ui->detailLayOut_3->setContentsMargins(MAIN_LAYOUT_MARGINS); + ui->verticalLayout_3->setContentsMargins(NO_MARGINS); + ui->availableLayout->setSpacing(SPACING); + + connect(m_wifiSwitch, &SwitchButton::disabledClick, this, [=]() { + showDesktopNotify(tr("No wireless network card detected")); + }); + + //开关 + if (QGSettings::isSchemaInstalled(GSETTINGS_SCHEMA)) { + m_switchGsettings = new QGSettings(GSETTINGS_SCHEMA); + connect(m_wifiSwitch, &SwitchButton::checkedChanged, this, [=] (bool checked) { + if (!m_interface->isValid()) { + return; + } + if (m_wifiSwitch->getDisabledFlag()) { + return; + } + qDebug() << "[WlanConnect]call setWirelessSwitchEnable " << checked << __LINE__; + m_interface->call(QStringLiteral("setWirelessSwitchEnable"),checked); + qDebug() << "[WlanConnect]call setWirelessSwitchEnable respond" << __LINE__; + }); + setSwitchStatus(); + connect(m_switchGsettings, &QGSettings::changed, this, [=] (const QString &key) { + if (key == WIRELESS_SWITCH) { + setSwitchStatus(); + } + }); + } else { + m_wifiSwitch->blockSignals(true); + m_wifiSwitch->setChecked(true); + m_wifiSwitch->blockSignals(false); + qDebug()<<"[netconnect] org.ukui.kylin-nm.switch is not installed!"; + } + + //获取设备列表 + getDeviceList(deviceList); + if (deviceList.isEmpty()) { + qDebug() << "[WlanConnect]no device exist when init, set switch disable"; + m_wifiSwitch->setDisabledFlag(true); + m_wifiSwitch->setChecked(false); + } + initNet(); + + if (deviceList.isEmpty() || !m_interface->isValid()) { + hideLayout(ui->availableLayout); + } + + // 有线网络断开或连接时刷新可用网络列表 + connect(m_interface, SIGNAL(wlanactiveConnectionStateChanged(QString, QString, QString, int)), this, SLOT(onActiveConnectionChanged(QString, QString, QString, int)), Qt::QueuedConnection); + //无线网络新增时添加网络 + connect(m_interface, SIGNAL(wlanAdd(QString, QStringList)), this, SLOT(onNetworkAdd(QString, QStringList)), Qt::QueuedConnection); + //删除无线网络 + connect(m_interface, SIGNAL(wlanRemove(QString, QString)), this, SLOT(onNetworkRemove(QString, QString)), Qt::QueuedConnection); + //网卡插拔处理 + connect(m_interface, SIGNAL(deviceStatusChanged()), this, SLOT(onDeviceStatusChanged()), Qt::QueuedConnection); + //信号更新处理 改为每过固定时间 主动获取 +// connect(m_interface, SIGNAL(signalStrengthChange(QString, QString, int)), this, SLOT(updateStrengthList(QString, QString, int))); + //网卡name处理 + connect(m_interface, SIGNAL(deviceNameChanged(QString, QString, int)), this, SLOT(onDeviceNameChanged(QString, QString, int)), Qt::QueuedConnection); + + connect(m_interface, SIGNAL(timeToUpdate()), this, SLOT(updateList()), Qt::QueuedConnection); + //高级设置 + connect(ui->detailBtn, &QPushButton::clicked, this, [=](bool checked) { + Q_UNUSED(checked) + runExternalApp(); + }); + + //定时20s扫描 + m_scanTimer = new QTimer(this); + m_scanTimer->start(SCANTIMER); + connect(m_scanTimer, &QTimer::timeout, this, &WlanConnect::reScan, Qt::QueuedConnection); + reScan(); + +// m_updateTimer = new QTimer(this); +// m_updateTimer->start(UPDATETIMER); + +} + +void WlanConnect::reScan() +{ + qDebug() << "time to rescan wifi"; + if (m_interface->isValid()) { + qDebug() << "[WlanConnect]call reScan" << __LINE__; + m_interface->call("reScan"); + qDebug() << "[WlanConnect]call reScan respond" << __LINE__; + } +} + +//更新列表顺序 +void WlanConnect::updateList() +{ + if (!m_wifiSwitch->isChecked()) { + return; + } + qDebug() << "update list"; + if(m_interface->isValid()) { + qDebug() << "[WlanConnect]call getWirelessList" << __LINE__; + QDBusMessage result = m_interface->call(QStringLiteral("getWirelessList")); + qDebug() << "[WlanConnect]call getWirelessList respond" << __LINE__; + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "getWirelessList error:" << result.errorMessage(); + return; + } + auto dbusArg = result.arguments().at(0).value(); + QMap> variantList; + dbusArg >> variantList; + + if (variantList.size() == 0) { + qDebug() << "[WlanConnect]updateList " << " list empty"; + return; + } + + QMap>::iterator iter; + + for (iter = variantList.begin(); iter != variantList.end(); iter++) { + if (deviceFrameMap.contains(iter.key())) { + QVector wifiList = iter.value(); + resortWifiList(deviceFrameMap[iter.key()], wifiList); + deviceFrameMap[iter.key()]->filletStyleChange(); + } + } + } +} + +void WlanConnect::resortWifiList(ItemFrame *frame, QVector list) +{ + if(nullptr == frame || frame->lanItemLayout->count() <= 0 || list.isEmpty()) { + return; + } + qDebug() << "begin resort" << frame->deviceFrame->deviceLabel->text(); + + int frameIndex = 0; + int listIndex = 1; + if (list.at(0).size() > 1) { + if (frame->itemMap.contains(list.at(0).at(0))) { + frame->lanItemLayout->removeWidget(frame->itemMap[list.at(0).at(0)]); + frame->lanItemLayout->insertWidget(0, frame->itemMap[list.at(0).at(0)]); + qDebug() << "active resort insert position 0" << list.at(0).at(0); + frame->itemMap[list.at(0).at(0)]->isAcitve = true; + frame->itemMap[list.at(0).at(0)]->uuid = list.at(0).at(3); + frame->uuid = list.at(0).at(3); + frame->itemMap[list.at(0).at(0)]->statusLabel->setText(tr("connected")); + updateIcon(frame->itemMap[list.at(0).at(0)], list.at(0).at(1), list.at(0).at(2), list.at(0).at(4)); + frameIndex ++; + } + } else { + qDebug() << " no active connection when resort"; + if (!frame->uuid.isEmpty()) { + QMap::iterator itemIter; + for (itemIter = frame->itemMap.begin(); itemIter != frame->itemMap.end(); itemIter++) { + if (itemIter.value()->uuid == frame->uuid ) { + WlanItem * item= nullptr; + item = itemIter.value(); + qDebug() << "a active connect missing when resort"; + itemIter.value()->uuid.clear(); + itemActiveConnectionStatusChanged(item, DEACTIVATED); + break; + } + } + } + frame->uuid.clear(); + } + + for ( ; listIndex < list.size(); listIndex++) { + if (frameIndex > frame->lanItemLayout->count() - 1) { + return; + } + if (frame->itemMap.contains(list.at(listIndex).at(0))) { + frame->lanItemLayout->removeWidget(frame->itemMap[list.at(listIndex).at(0)]); + frame->lanItemLayout->insertWidget(frameIndex, frame->itemMap[list.at(listIndex).at(0)]); + qDebug() << "custom resort " << list.at(listIndex).at(0) <<" insert position" << frameIndex; + if (frame->itemMap[list.at(listIndex).at(0)]->isAcitve) { + frame->itemMap[list.at(listIndex).at(0)]->isAcitve = false; + frame->itemMap[list.at(listIndex).at(0)]->uuid.clear(); + frame->itemMap[list.at(listIndex).at(0)]->statusLabel->setText(""); + } + updateIcon(frame->itemMap[list.at(listIndex).at(0)], list.at(listIndex).at(1), list.at(listIndex).at(2), list.at(listIndex).at(3)); + frameIndex++; + } else { + qDebug() << "not find " << list.at(listIndex).at(0) << " in current list, ignore"; + } + } + qDebug() << "resort finish"; +} + +void WlanConnect::updateIcon(WlanItem *item, QString signalStrength, QString security, QString isApConnection) +{ + qDebug() << "updateIcon" << item->titileLabel->text(); + + int sign = setSignal(signalStrength); + bool isLock = true; + if (security.isEmpty()) { + isLock = false; + } else { + isLock = true; + } + + QString iconamePath; + if (isApConnection == IsApConnection) { + iconamePath = KApSymbolic; + } else { + iconamePath = wifiIcon(isLock, sign); + } + QIcon searchIcon = QIcon::fromTheme(iconamePath); + if (iconamePath != KLanSymbolic && iconamePath != NoNetSymbolic) { + item->iconLabel->setProperty("useIconHighlightEffect", 0x10); + } + item->iconLabel->setPixmap(searchIcon.pixmap(searchIcon.actualSize(QSize(24, 24)))); + qDebug() << "updateIcon" << item->titileLabel->text() << " finish"; +} + +//wifi strength update +//void WlanConnect::updateStrengthList(QString deviceName, QString ssid, int strength) +//{ +// return; +// if(!m_wifiSwitch->isChecked()) { +// return; +// } +// qDebug()<<"[WlanConnect]Update wireless network signal strength:" << deviceName <::iterator iters; +// for (iters = deviceWlanlistInfo.deviceLayoutMap.begin(); iters != deviceWlanlistInfo.deviceLayoutMap.end(); iters++) { +// if (iters.key() == deviceName) { +// qDebug() << "[WlanConnect] updateStrengthList find " << deviceName << " in deviceWlanlistInfo.deviceLayoutMap"; +// if (iters.value()->lanItemLayout->layout() != NULL) { +// WlanItem* item = nullptr; +// QMap::iterator iter; +// for (iter = deviceWlanlistInfo.wlanItemMap.begin(); iter != deviceWlanlistInfo.wlanItemMap.end(); iter++) { +// if (iter.key() == ssid) { +// item = iter.value(); +// break; +// } +// } +// isLock = item->isLock; +// //remove the item from layout +// iters.value()->lanItemLayout->removeWidget(item); +// //get position +// int index = sortWlanNet(deviceName,ssid, QString::number(strength)); +// //add the item to new position +// qDebug()<<"更新后位置:"<iconLabel->setProperty("useIconHighlightEffect", 0x10); +// } +// item->iconLabel->setPixmap(searchIcon.pixmap(searchIcon.actualSize(QSize(24, 24)))); + +// iters.value()->lanItemLayout->insertWidget(index, item); +// } +// } +// } +//} + +//device add or remove================================= +void WlanConnect::onDeviceStatusChanged() +{ + qDebug()<<"[WlanConnect]onDeviceStatusChanged"; + QEventLoop eventloop; + QTimer::singleShot(300, &eventloop, SLOT(quit())); + eventloop.exec(); + QStringList list; + getDeviceList(list); + + QStringList removeList,addList; + + //remove的设备 + for (int i = 0; i< deviceList.size(); ++i) { + if (!list.contains(deviceList.at(i))) { + qDebug() << "[WlanConnect]onDeviceStatusChanged " << deviceList.at(i) << "was removed"; + removeList << deviceList.at(i); + } + } + + //add的设备 + for (int i = 0; i< list.size(); ++i) { + if (!deviceList.contains(list.at(i))) { + qDebug() << "[WlanConnect]onDeviceStatusChanged " << list.at(i) << "was add"; + addList << list.at(i); + } + } + + for (int i = 0; i < removeList.size(); ++i) { + removeDeviceFrame(removeList.at(i)); + } + + for (int i = 0; i < addList.size(); ++i) { + addDeviceFrame(addList.at(i)); + } + deviceList = list; + if (deviceList.isEmpty()) { + m_wifiSwitch->setDisabledFlag(true); + m_wifiSwitch->setChecked(false); + } else { + m_wifiSwitch->setDisabledFlag(false); + setSwitchStatus(); + } +} + +void WlanConnect::onDeviceNameChanged(QString oldName, QString newName, int type) +{ + if (WIRELESS_TYPE != type || !deviceFrameMap.contains(oldName) || !deviceList.contains(oldName)) { + qDebug() << "[WlanConnect]onDeviceNameChanged no such device " << oldName; + return; + } + + if (deviceFrameMap.contains(newName) && deviceList.contains(newName)) { + qDebug() << "[WlanConnect]onDeviceNameChanged already has device " << newName; + return; + } + + qDebug() << "[WlanConnect]onDeviceNameChanged " << oldName << "change to" << newName; + + //shan chu chong jian + removeDeviceFrame(oldName); + removeDeviceFrame(newName); + + getDeviceList(deviceList); + if (deviceList.contains(newName)) { + addDeviceFrame(newName); + initNetListFromDevice(newName); + } +} + +//activeconnect status change +void WlanConnect::onActiveConnectionChanged(QString deviceName, QString ssid, QString uuid, int status) +{ + if (!m_wifiSwitch->isChecked()) { + return; + } + if (uuid.isEmpty()) { + return; + } + WlanItem * item= nullptr; + //device ssid 有可能均为空 + if (deviceName.isEmpty() || ssid.isEmpty()) { + if (status == ACTIVATING || status == ACTIVATED) { + return; + } + QMap::iterator iter; + for (iter = deviceFrameMap.begin(); iter != deviceFrameMap.end(); iter++) { + if (uuid == iter.value()->uuid) { + QMap::iterator itemIter; + for (itemIter = iter.value()->itemMap.begin(); itemIter != iter.value()->itemMap.end(); itemIter++) { + if (itemIter.value()->uuid == uuid ) { + item = itemIter.value(); + if (status == DEACTIVATED) { + itemIter.value()->uuid.clear(); + } + break; + } + } + break; + } + } + } else { + if (!deviceFrameMap.contains(deviceName)) { + return; + } + for (int i = 0; i < deviceFrameMap[deviceName]->itemMap.size(); ++i) { + if (deviceFrameMap[deviceName]->itemMap.contains(ssid)) { + item = deviceFrameMap[deviceName]->itemMap[ssid]; + if (status == ACTIVATED || status == ACTIVATING) { + deviceFrameMap[deviceName]->itemMap[ssid]->uuid = uuid; + deviceFrameMap[deviceName]->uuid = uuid; + if (status == ACTIVATED) { + deviceFrameMap[deviceName]->lanItemLayout->removeWidget(item); + deviceFrameMap[deviceName]->lanItemLayout->insertWidget(0,item); + deviceFrameMap[deviceName]->filletStyleChange(); + } + } else if (status == DEACTIVATED) { + deviceFrameMap[deviceName]->itemMap[ssid]->uuid.clear(); + deviceFrameMap[deviceName]->uuid.clear(); + //todo 断开后排序 现在等下次更新列表 自动排序 + } + break; + } + } + } + + if (nullptr != item) { + itemActiveConnectionStatusChanged(item, status); + } +} + +//wifi add=============================================================== +void WlanConnect::onNetworkAdd(QString deviceName, QStringList wlanInfo) +{ + qDebug()<<"[WlanConnect]onNetworkAdd "<< deviceName << " " << wlanInfo; + if(!m_wifiSwitch->isChecked() || deviceName.isEmpty()) { + return; + } + + if (!deviceList.contains(deviceName)) { + qDebug() << "[WlanConnect]onNetworkAdd not contain " << deviceName << "then add"; + deviceList.append(deviceName); + addDeviceFrame(deviceName); + onNetworkAdd(deviceName, wlanInfo); + return; + } + + bool isLock = true; + if (wlanInfo.at(2) == "") { + isLock = false; + } else { + isLock = true; + } + + QMap::iterator iter; + for (iter = deviceFrameMap.begin(); iter != deviceFrameMap.end(); iter++) { + if (deviceName == iter.key()) { + addOneWlanFrame(iter.value(), deviceName, wlanInfo.at(0), wlanInfo.at(1), "", isLock, false, WIRELESS_TYPE, wlanInfo.at(3)); + } + } + +} + +//wifi remove ============================================================= +void WlanConnect::onNetworkRemove(QString deviceName, QString wlannName) +{ + //开关已关闭 忽略 +// if (!m_wifiSwitch->isChecked()) { +// qDebug() << "[WlanConnect]recieve network remove,but wireless switch is off"; +// return; +// } + //当前无此设备 忽略 + if (deviceName.isEmpty() || !deviceFrameMap.contains(deviceName)) { + qDebug() << "[WlanConnect]recieve network remove,but no such device:" << deviceName; + return; + } + qDebug()<<"[WlanConnect]Wifi remove device:" << deviceName << ",wlan name:" << wlannName; + QMap::iterator iter; + for (iter = deviceFrameMap.begin(); iter != deviceFrameMap.end(); iter++) { + if (deviceName == iter.key()) { + removeOneWlanFrame(iter.value(), deviceName, wlannName); + } + } +} + +//获取设备列表======================================================= +void WlanConnect::getDeviceList(QStringList &list) +{ + if (!m_interface->isValid()) { + return; + } + qDebug() << "[WlanConnect]call getDeviceListAndEnabled" << __LINE__; + QDBusMessage result = m_interface->call(QStringLiteral("getDeviceListAndEnabled"),1); + qDebug() << "[WlanConnect]call getDeviceListAndEnabled respond" << __LINE__; + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "[WlanConnect]getWirelessDeviceList error:" << result.errorMessage(); + return; + } + auto dbusArg = result.arguments().at(0).value(); + QMap map; + dbusArg >> map; + list = map.keys(); +} + +//设置开关 +void WlanConnect::setSwitchStatus() +{ +// if (deviceList.size() == 0) { +// m_wifiSwitch->blockSignals(true); +// m_wifiSwitch->setChecked(false); +// m_wifiSwitch->blockSignals(false); +// return; +// } + bool status = m_switchGsettings->get(WIRELESS_SWITCH).toBool(); + qDebug() << "[WlanConnect]setSwitchStatus" << status; + m_wifiSwitch->blockSignals(true); + m_wifiSwitch->setChecked(status); + m_wifiSwitch->blockSignals(false); + if (!m_wifiSwitch->isChecked()) { + hideLayout(ui->availableLayout); + } else { + showLayout(ui->availableLayout); + } +} + +//初始化整体列表和单设备列表 +void WlanConnect::initNet() { +// int count = 1; + //先构建每个设备的列表头 + for (int i = 0; i < deviceList.size(); ++i) { + addDeviceFrame(deviceList.at(i)); + } + //再填充每个设备的列表 + for (int i = 0; i < deviceList.size(); ++i) { + initNetListFromDevice(deviceList.at(i)); + } +} + +//初始化设备列表 网卡标号问题? +void WlanConnect::initNetListFromDevice(QString deviceName) +{ + qDebug() << "[WlanConnect]initNetListFromDevice " << deviceName; + if (!m_wifiSwitch->isChecked()) { + qDebug() << "[WlanConnect]initNetListFromDevice " << deviceName << " switch off"; + return; + } + if (!deviceFrameMap.contains(deviceName)) { + qDebug() << "[WlanConnect]initNetListFromDevice " << deviceName << " not exist"; + return; + } + if (!m_interface->isValid()) { + return; + } + qDebug() << "[WlanConnect]call getWirelessList" << __LINE__; + QDBusMessage result = m_interface->call(QStringLiteral("getWirelessList")); + qDebug() << "[WlanConnect]call getWirelessList respond" << __LINE__; + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "getWirelessList error:" << result.errorMessage(); + return; + } + auto dbusArg = result.arguments().at(0).value(); + QMap> variantList; + dbusArg >> variantList; + if (variantList.size() == 0) { + qDebug() << "[WlanConnect]initNetListFromDevice " << deviceName << " list empty"; + return; + } + QMap>::iterator iter; + + for (iter = variantList.begin(); iter != variantList.end(); iter++) { + if (deviceName == iter.key()) { + QVector wlanListInfo = iter.value(); + //处理列表 已连接 + qDebug() << "[WlanConnect]initNetListFromDevice " << deviceName << " acitved wifi " << wlanListInfo.at(0); + addActiveItem(deviceFrameMap[deviceName], deviceName, wlanListInfo.at(0)); + //处理列表 未连接 + for (int i = 1; i < wlanListInfo.length(); i++) { + qDebug() << "[WlanConnect]initNetListFromDevice " << deviceName << " deacitved wifi " << wlanListInfo.at(i); + addCustomItem(deviceFrameMap[deviceName], deviceName, wlanListInfo.at(i)); + } + } + } + return; +} + +//高级设置 +void WlanConnect::runExternalApp() { + QString cmd = "nm-connection-editor"; + QProcess process(this); + process.startDetached(cmd); +} + +//根据信号强度分级+安全性分图标 +QString WlanConnect::wifiIcon(bool isLock, int strength) { + switch (strength) { + case 1: + return isLock ? KWifiLockSymbolic : KWifiSymbolic; + case 2: + return isLock ? KWifiLockGood : KWifiGood; + case 3: + return isLock ? KWifiLockOK : KWifiOK; + case 4: + return isLock ? KWifiLockLow : KWifiLow; + case 5: + return isLock ? KWifiLockNone : KWifiNone; + default: + return ""; + } +} + +//根据信号强度分级 +int WlanConnect::setSignal(QString lv) { + int signal = lv.toInt(); + int signalLv = 0; + + if (signal > 75) { + signalLv = 1; + } else if (signal > 55 && signal <= 75) { + signalLv = 2; + } else if (signal > 35 && signal <= 55) { + signalLv = 3; + } else if (signal > 15 && signal <= 35) { + signalLv = 4; + } else if (signal <= 15) { + signalLv = 5; + } + return signalLv; +} + +//隐藏 +void WlanConnect::hideLayout(QVBoxLayout * layout) { + for (int i = layout->layout()->count()-1; i >= 0; --i) { + QLayoutItem *it = layout->layout()->itemAt(i); + ItemFrame *itemFrame = qobject_cast(it->widget()); + itemFrame->hide(); + } +} + +//显示 +void WlanConnect::showLayout(QVBoxLayout * layout) { + for (int i = layout->layout()->count()-1; i >= 0; --i) { + QLayoutItem *it = layout->layout()->itemAt(i); + ItemFrame *itemFrame = qobject_cast(it->widget()); + itemFrame->show(); + } +} + +//获取应该插入哪个位置 +int WlanConnect::sortWlanNet(QString deviceName, QString name, QString signal) +{ + qDebug() << "[WlanConnect]call getWirelessList" << __LINE__; + QDBusMessage result = m_interface->call(QStringLiteral("getWirelessList")); + qDebug() << "[WlanConnect]call getWirelessList respond" << __LINE__; + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "getWirelessList error:" << result.errorMessage(); + return 0; + } + auto dbusArg = result.arguments().at(0).value(); + QMap> variantList; + dbusArg >> variantList; + QMap>::iterator iter; + for (iter = variantList.begin(); iter != variantList.end(); iter++) { + if (deviceName == iter.key()) { + QVector wlanListInfo = iter.value(); + for (int i = 0; i < wlanListInfo.size(); i++) { + if (name == wlanListInfo.at(i).at(0)) { + return i; + } + } + } + } + return 0; +} + +void WlanConnect::activeConnect(QString netName, QString deviceName, int type) { + if (!m_interface->isValid()) { + return; + } + qDebug() << "[WlanConnect]call activateConnect" << __LINE__; + m_interface->call("activateConnect",type, deviceName, netName); + qDebug() << "[WlanConnect]call activateConnect respond" << __LINE__; +} + +void WlanConnect::deActiveConnect(QString netName, QString deviceName, int type) { + if (!m_interface->isValid()) { + return; + } + qDebug() << "[WlanConnect]call deActivateConnect" << __LINE__; + m_interface->call("deActivateConnect",type, deviceName, netName); + qDebug() << "[WlanConnect]call deActivateConnect respond" << __LINE__; +} + + +//处理列表 已连接 +void WlanConnect::addActiveItem(ItemFrame *frame, QString devName, QStringList infoList) +{ + if (frame == nullptr) { + return; + } + if (infoList.size() == 1) { + return; + } + + bool isLock = true; + if (infoList.at(2) == "") { + isLock = false; + } else { + isLock = true; + } + addOneWlanFrame(frame, devName, infoList.at(0), infoList.at(1), infoList.at(3), isLock, true, WIRELESS_TYPE, infoList.at(4)); +} + +//处理列表 未连接 +void WlanConnect::addCustomItem(ItemFrame *frame, QString devName, QStringList infoList) +{ + if (frame == nullptr) { + return; + } + bool isLock = true; + if (infoList.at(2) == "") { + isLock = false; + } else { + isLock = true; + } + addOneWlanFrame(frame, devName, infoList.at(0), infoList.at(1), "", isLock, false, WIRELESS_TYPE, infoList.at(3)); +} + +//增加设备 +void WlanConnect::addDeviceFrame(QString devName) +{ + qDebug() << "[WlanConnect]addDeviceFrame " << devName; + ItemFrame *itemFrame = new ItemFrame(devName, pluginWidget); + ui->availableLayout->addWidget(itemFrame); + itemFrame->deviceFrame->deviceLabel->setText(tr("card")+/*QString("%1").arg(count)+*/":"+devName); + deviceFrameMap.insert(devName, itemFrame); +} + +//减少设备 +void WlanConnect::removeDeviceFrame(QString devName) +{ + qDebug() << "[WlanConnect]removeDeviceFrame " << devName; + if (deviceFrameMap.contains(devName)) { + ItemFrame *item = deviceFrameMap[devName]; + if (item->lanItemFrame->layout() != NULL) { + QLayoutItem* layoutItem; + while ((layoutItem = item->lanItemFrame->layout()->takeAt(0)) != NULL) { + delete layoutItem->widget(); + delete layoutItem; + item = nullptr; + } + item->itemMap.clear(); + } + delete item; + item = nullptr; + deviceFrameMap.remove(devName); + } +} + +//增加ap +void WlanConnect::addOneWlanFrame(ItemFrame *frame, QString deviceName, QString name, QString signal, QString uuid, bool isLock, bool status, int type, QString isApConnection) +{ + if (nullptr == frame) { + return; + } + + bool bApConnection = (isApConnection == IsApConnection); + + if (frame->itemMap.contains(name)) { + qDebug() << "[WlanConnect]Already exist a wifi " << name << " in " << deviceName; + return; + } + //设置单项的信息 + int sign = setSignal(signal); + WlanItem * wlanItem = new WlanItem(status, isLock, pluginWidget); + QString iconamePath; + if (bApConnection) { + iconamePath = KApSymbolic; + } else { + iconamePath = wifiIcon(isLock, sign); + } + if (iconamePath != KLanSymbolic && iconamePath != NoNetSymbolic) { + wlanItem->iconLabel->setProperty("useIconHighlightEffect", 0x10); + } + QIcon searchIcon = QIcon::fromTheme(iconamePath); + wlanItem->iconLabel->setPixmap(searchIcon.pixmap(searchIcon.actualSize(QSize(24, 24)))); + wlanItem->titileLabel->setText(name); + if (status) { + wlanItem->statusLabel->setText(tr("connected")); + frame->uuid = uuid; + wlanItem->uuid = uuid; + } else { + wlanItem->statusLabel->setText(""); + } + + connect(wlanItem->infoLabel, &InfoButton::clicked, this, [=]{ + // open detail page + if (!m_interface->isValid()) { + return; + } + qDebug() << "[WlanConnect]call showPropertyWidget" << __LINE__; + m_interface->call(QStringLiteral("showPropertyWidget"), deviceName, name); + qDebug() << "[WlanConnect]call showPropertyWidget respond" << __LINE__; + }); + + connect(wlanItem, &QPushButton::clicked, this, [=] { + if (wlanItem->isAcitve) { + deActiveConnect(name, deviceName, type); + } else { + activeConnect(name, deviceName, type); + } + }); + //记录到deviceFrame的itemMap中 + deviceFrameMap[deviceName]->itemMap.insert(name, wlanItem); + int index; + if (status) { + index = 0; + } else { + index = sortWlanNet(deviceName, name, signal); + } + qDebug()<<"insert " << name << " to " << deviceName << " list, postion " << index; + frame->lanItemLayout->insertWidget(index, wlanItem); + frame->filletStyleChange(); +} + +//减少ap +void WlanConnect::removeOneWlanFrame(ItemFrame *frame, QString deviceName, QString ssid) +{ + if (nullptr == frame) { + return; + } + + if (frame->itemMap.contains(ssid)) { + qDebug() << "[WlanConnect]removeOneWlanFrame " << deviceName << ssid; + frame->lanItemLayout->removeWidget(frame->itemMap[ssid]); + delete frame->itemMap[ssid]; + frame->itemMap.remove(ssid); + frame->filletStyleChange(); + } +} + +void WlanConnect::itemActiveConnectionStatusChanged(WlanItem *item, int status) +{ + if (status == ACTIVATING) { + item->startLoading(); + } else if (status == ACTIVATED) { + item->stopLoading(); + item->statusLabel->clear(); + item->statusLabel->setMinimumSize(36,36); + item->statusLabel->setMaximumSize(16777215,16777215); + item->statusLabel->setText(tr("connected")); + item->isAcitve = true; + } else if (status == DEACTIVATING) { + item->startLoading(); + } else if (status == DEACTIVATED) { + item->stopLoading(); + item->statusLabel->clear(); + item->statusLabel->setMinimumSize(36,36); + item->statusLabel->setMaximumSize(16777215,16777215); + item->isAcitve = false; + } +} + diff --git a/plugins/wlanconnect/wlanconnect.h b/plugins/wlanconnect/wlanconnect.h new file mode 100644 index 00000000..12550bbe --- /dev/null +++ b/plugins/wlanconnect/wlanconnect.h @@ -0,0 +1,165 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. + * + * 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 WLANCONNECT_H +#define WLANCONNECT_H + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include "switchbutton.h" +#include "hoverbtn.h" +#include "itemframe.h" +#include "wlanitem.h" +namespace Ui { +class WlanConnect; +} + + +class WlanConnect : public QObject, CommonInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") + Q_INTERFACES(CommonInterface) + +public: + WlanConnect(); + ~WlanConnect(); + + QString plugini18nName() Q_DECL_OVERRIDE; + int pluginTypes() Q_DECL_OVERRIDE; + QWidget * pluginUi() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; + bool isShowOnHomePage() const Q_DECL_OVERRIDE; + QIcon icon() const Q_DECL_OVERRIDE; + bool isEnable() const Q_DECL_OVERRIDE; + QString translationPath() const Q_DECL_OVERRIDE; + +private: + void initComponent(); + void runExternalApp(); + void initSearchText(); + + void showDesktopNotify(const QString &message); + + //点击item 连接/断开 + void activeConnect(QString netName, QString deviceName, int type); + void deActiveConnect(QString netName, QString deviceName, int type); + + + + int sortWlanNet(QString deviceName, QString name, QString signal); + void updateIcon(WlanItem *item, QString signalStrength, QString security, QString isApConnection); + void resortWifiList(ItemFrame *frame, QVector list); + + + //单wifi图标 + int setSignal(QString lv); + QString wifiIcon(bool isLock, int strength); + + + //开关相关 + void setSwitchStatus(); + void hideLayout(QVBoxLayout * layout); + void showLayout(QVBoxLayout * layout); + + + //获取设备列表 + void getDeviceList(QStringList &list); + //初始化设备wifi列表 + void initNet(); + void initNetListFromDevice(QString deviceName); + //处理列表 已连接 + void addActiveItem(ItemFrame *frame, QString devName, QStringList infoList); + //处理列表 未连接 + void addCustomItem(ItemFrame *frame, QString devName, QStringList infoList); + //增加设备 + void addDeviceFrame(QString devName); + //减少设备 + void removeDeviceFrame(QString devName); + //增加ap + void addOneWlanFrame(ItemFrame *frame, QString deviceName, QString name, QString signal, QString uuid, bool isLock, bool status, int type, QString isApConnection); + //减少ap + void removeOneWlanFrame(ItemFrame *frame, QString deviceName, QString ssid); + + + //单个wifi连接状态变化 + void itemActiveConnectionStatusChanged(WlanItem *item, int status); +protected: + bool eventFilter(QObject *w,QEvent *e); + +private: + Ui::WlanConnect *ui; + + QString pluginName; + int pluginType; + QWidget *pluginWidget; + + QDBusInterface *m_interface = nullptr; + + QGSettings *m_switchGsettings = nullptr; + + //设备列表 + QStringList deviceList; + //设备名 + 单设备frame + QMap deviceFrameMap; + + //QVector wlanSignalList; +// DeviceWlanlistInfo deviceWlanlistInfo; + + QTimer * m_scanTimer = nullptr; +// QTimer * m_updateTimer = nullptr; +private: + SwitchButton *m_wifiSwitch; + bool m_firstLoad; + +private slots: + + void onNetworkAdd(QString deviceName, QStringList wlanInfo); + void onNetworkRemove(QString deviceName, QString wlannName); + void onActiveConnectionChanged(QString deviceName, QString ssid, QString uuid, int status); + + void updateList(); + void onDeviceStatusChanged(); + void onDeviceNameChanged(QString, QString, int); + + void reScan(); + + +}; +#endif // WLANCONNECT_H diff --git a/plugins/wlanconnect/wlanconnect.pro b/plugins/wlanconnect/wlanconnect.pro new file mode 100644 index 00000000..86fef538 --- /dev/null +++ b/plugins/wlanconnect/wlanconnect.pro @@ -0,0 +1,51 @@ +QT += widgets network dbus gui core +TEMPLATE = lib +CONFIG += plugin + +include(../component/drownlabel.pri) + +TARGET = $$qtLibraryTarget(wlanconnect) +DESTDIR = ../.. +target.path = $$[QT_INSTALL_LIBS]/ukui-control-center +trans.files = translations/* +trans.path = /usr/share/kylin-nm/wlanconnect/ + +INCLUDEPATH += \ + $$PROJECT_COMPONENTSOURCE \ + $$PROJECT_ROOTDIR \ + /usr/include/ukcc/interface \ + /usr/include/ukcc/widgets + +LIBS += -L$$[QT_INSTALL_LIBS] -lgsettings-qt -lukcc + +CONFIG += c++11 \ + link_pkgconfig \ + +PKGCONFIG += gsettings-qt \ + +#DEFINES += QT_DEPRECATED_WARNINGS + +SOURCES += \ + deviceframe.cpp \ +# drownlabel.cpp \ + itemframe.cpp \ + wlanconnect.cpp \ + wlanitem.cpp + +HEADERS += \ + deviceframe.h \ +# drownlabel.h \ + itemframe.h \ + wlanconnect.h \ + wlanitem.h + +FORMS += \ + wlanconnect.ui + +INSTALLS += target \ + trans + +TRANSLATIONS += \ + translations/zh_CN.ts \ + translations/tr.ts \ + translations/bo.ts diff --git a/plugins/wlanconnect/wlanconnect.ui b/plugins/wlanconnect/wlanconnect.ui new file mode 100644 index 00000000..fa8cfe41 --- /dev/null +++ b/plugins/wlanconnect/wlanconnect.ui @@ -0,0 +1,192 @@ + + + WlanConnect + + + + 0 + 0 + 885 + 700 + + + + WlanConnect + + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + WLAN + + + true + + + + + + + 1 + + + 0 + + + + + + 0 + 60 + + + + + 16777215 + 50 + + + + QFrame::Box + + + + 18 + + + 0 + + + 9 + + + 0 + + + + + 16 + + + + + + 118 + 0 + + + + open + + + + + + + Qt::Horizontal + + + + 523 + 20 + + + + + + + + + + + + + + + + + 1 + + + + + + + 8 + + + + + + 120 + 36 + + + + + 16777215 + 36 + + + + Advanced settings + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + TitleLabel + QLabel +
titlelabel.h
+
+
+ + +
diff --git a/plugins/wlanconnect/wlanitem.cpp b/plugins/wlanconnect/wlanitem.cpp new file mode 100644 index 00000000..5d1bbf3c --- /dev/null +++ b/plugins/wlanconnect/wlanitem.cpp @@ -0,0 +1,90 @@ +#include "wlanitem.h" +#include +#define FRAME_SPEED 150 +#define LIMIT_TIME 60*1000 +#define TOTAL_PAGE 8 +#define RADIUS 6.0 + +#define THEME_QT_SCHEMA "org.ukui.style" +#define MODE_QT_KEY "style-name" + +WlanItem::WlanItem(bool bAcitve, bool isLock, QWidget *parent) + : isAcitve(bAcitve), isLock(isLock), QPushButton(parent) +{ + this->setMinimumSize(550, 58); + this->setProperty("useButtonPalette", true); + setStyleSheet("QPushButton:!checked{background-color: palette(base)}"); + QHBoxLayout *mLanLyt = new QHBoxLayout(this); + mLanLyt->setContentsMargins(16,0,16,0); + mLanLyt->setSpacing(16); + iconLabel = new QLabel(this); + titileLabel = new FixLabel(this); + statusLabel = new QLabel(this); + statusLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); +// statusLabel->setMinimumSize(36,36); + infoLabel = new InfoButton(this); + mLanLyt->addWidget(iconLabel); + mLanLyt->addWidget(titileLabel,Qt::AlignLeft); + mLanLyt->addStretch(); + mLanLyt->addWidget(statusLabel); + mLanLyt->addWidget(infoLabel); + + loadIcons.append(QIcon::fromTheme("ukui-loading-1-symbolic")); + loadIcons.append(QIcon::fromTheme("ukui-loading-2-symbolic")); + loadIcons.append(QIcon::fromTheme("ukui-loading-3-symbolic")); + loadIcons.append(QIcon::fromTheme("ukui-loading-4-symbolic")); + loadIcons.append(QIcon::fromTheme("ukui-loading-5-symbolic")); + loadIcons.append(QIcon::fromTheme("ukui-loading-6-symbolic")); + loadIcons.append(QIcon::fromTheme("ukui-loading-7-symbolic")); + + waitTimer = new QTimer(this); + connect(waitTimer, &QTimer::timeout, this, &WlanItem::updateIcon); + +} + +WlanItem::~WlanItem() +{ + +} + +void WlanItem::updateIcon() +{ + if (currentIconIndex > 6) { + currentIconIndex = 0; + } + statusLabel->setPixmap(loadIcons.at(currentIconIndex).pixmap(16,16)); + currentIconIndex ++; +} + +void WlanItem::startLoading() +{ + waitTimer->start(FRAME_SPEED); + loading = true; +} + +void WlanItem::stopLoading(){ + waitTimer->stop(); + loading = false; +} + +void WlanItem::paintEvent(QPaintEvent *event) +{ + QPalette pal = this->palette(); + + QPainter painter(this); + painter.setRenderHint(QPainter:: Antialiasing, true); //设置渲染,启动反锯齿 + painter.setPen(Qt::NoPen); + painter.setBrush(pal.color(QPalette::Base)); + + QRect rect = this->rect(); + if (!useHalfFillet) { + painter.drawRect(rect); + } else { + QPainterPath path; + path.addRoundedRect (rect, RADIUS, RADIUS); + QRect temp_rect(rect.left(), rect.top(), rect.width(), rect.height()/2); + path.addRect(temp_rect); + painter.drawPath(path); + } + QPushButton::paintEvent(event); +} diff --git a/plugins/wlanconnect/wlanitem.h b/plugins/wlanconnect/wlanitem.h new file mode 100644 index 00000000..9d24757d --- /dev/null +++ b/plugins/wlanconnect/wlanitem.h @@ -0,0 +1,52 @@ +#ifndef WLANITEM_H +#define WLANITEM_H +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fixlabel.h" +#include "infobutton.h" + +class WlanItem : public QPushButton +{ +public: + WlanItem(bool bAcitve, bool isLock, QWidget *parent = nullptr); + ~WlanItem(); +public: + QLabel * iconLabel = nullptr; + InfoButton * infoLabel = nullptr; + FixLabel * titileLabel = nullptr; + QLabel * statusLabel = nullptr; + QString uuid = ""; + + void setHalfFillet(bool flag) {useHalfFillet = flag; repaint();} +public: + void startLoading(); + void stopLoading(); + bool isAcitve = false; + bool loading = false; + bool isLock = false; + + + +protected: + void paintEvent(QPaintEvent *event); + +private: + QTimer *waitTimer = nullptr; + QGSettings *themeGsettings = nullptr; + bool useHalfFillet = false; + QList loadIcons; + int currentIconIndex=0; + +private slots: + void updateIcon(); + +}; + +#endif // WLANITEM_H diff --git a/res.qrc b/res.qrc new file mode 100644 index 00000000..7646d2b3 --- /dev/null +++ b/res.qrc @@ -0,0 +1 @@ + diff --git a/res/g/close_black.png b/res/g/close_black.png new file mode 100644 index 00000000..237e5552 Binary files /dev/null and b/res/g/close_black.png differ diff --git a/res/g/close_white.png b/res/g/close_white.png new file mode 100644 index 00000000..0943a4bb Binary files /dev/null and b/res/g/close_white.png differ diff --git a/res/g/down_arrow.png b/res/g/down_arrow.png new file mode 100644 index 00000000..c7a343b3 Binary files /dev/null and b/res/g/down_arrow.png differ diff --git a/res/h/hide-pwd.png b/res/h/hide-pwd.png new file mode 100644 index 00000000..c1d30447 Binary files /dev/null and b/res/h/hide-pwd.png differ diff --git a/res/h/no-pwd-wifi.png b/res/h/no-pwd-wifi.png new file mode 100644 index 00000000..dbec54a3 Binary files /dev/null and b/res/h/no-pwd-wifi.png differ diff --git a/res/h/right-pwd.png b/res/h/right-pwd.png new file mode 100644 index 00000000..1bbc00d1 Binary files /dev/null and b/res/h/right-pwd.png differ diff --git a/res/h/show-pwd.png b/res/h/show-pwd.png new file mode 100644 index 00000000..08c4de51 Binary files /dev/null and b/res/h/show-pwd.png differ diff --git a/res/hw/wifi-full-pwd.png b/res/hw/wifi-full-pwd.png new file mode 100644 index 00000000..065f7f8e Binary files /dev/null and b/res/hw/wifi-full-pwd.png differ diff --git a/res/hw/wifi-full.png b/res/hw/wifi-full.png new file mode 100644 index 00000000..48024d04 Binary files /dev/null and b/res/hw/wifi-full.png differ diff --git a/res/hw/wifi-high-pwd.png b/res/hw/wifi-high-pwd.png new file mode 100644 index 00000000..81a4d11e Binary files /dev/null and b/res/hw/wifi-high-pwd.png differ diff --git a/res/hw/wifi-high.png b/res/hw/wifi-high.png new file mode 100644 index 00000000..3ec53052 Binary files /dev/null and b/res/hw/wifi-high.png differ diff --git a/res/hw/wifi-low-pwd.png b/res/hw/wifi-low-pwd.png new file mode 100644 index 00000000..784ad1b2 Binary files /dev/null and b/res/hw/wifi-low-pwd.png differ diff --git a/res/hw/wifi-low.png b/res/hw/wifi-low.png new file mode 100644 index 00000000..3fe8bded Binary files /dev/null and b/res/hw/wifi-low.png differ diff --git a/res/hw/wifi-medium-pwd.png b/res/hw/wifi-medium-pwd.png new file mode 100644 index 00000000..221fdbc1 Binary files /dev/null and b/res/hw/wifi-medium-pwd.png differ diff --git a/res/hw/wifi-medium.png b/res/hw/wifi-medium.png new file mode 100644 index 00000000..3b1683f3 Binary files /dev/null and b/res/hw/wifi-medium.png differ diff --git a/res/hw/wifi-none-pwd.png b/res/hw/wifi-none-pwd.png new file mode 100644 index 00000000..109f19ee Binary files /dev/null and b/res/hw/wifi-none-pwd.png differ diff --git a/res/hw/wifi-none.png b/res/hw/wifi-none.png new file mode 100644 index 00000000..0a3bdd14 Binary files /dev/null and b/res/hw/wifi-none.png differ diff --git a/res/hw/wifi6+-full-pwd.png b/res/hw/wifi6+-full-pwd.png new file mode 100644 index 00000000..b2936c6f Binary files /dev/null and b/res/hw/wifi6+-full-pwd.png differ diff --git a/res/hw/wifi6+-full.png b/res/hw/wifi6+-full.png new file mode 100644 index 00000000..faf2297d Binary files /dev/null and b/res/hw/wifi6+-full.png differ diff --git a/res/hw/wifi6+-high-pwd.png b/res/hw/wifi6+-high-pwd.png new file mode 100644 index 00000000..684d51f6 Binary files /dev/null and b/res/hw/wifi6+-high-pwd.png differ diff --git a/res/hw/wifi6+-high.png b/res/hw/wifi6+-high.png new file mode 100644 index 00000000..0ffb9ff9 Binary files /dev/null and b/res/hw/wifi6+-high.png differ diff --git a/res/hw/wifi6+-low-pwd.png b/res/hw/wifi6+-low-pwd.png new file mode 100644 index 00000000..c2b8ece5 Binary files /dev/null and b/res/hw/wifi6+-low-pwd.png differ diff --git a/res/hw/wifi6+-low.png b/res/hw/wifi6+-low.png new file mode 100644 index 00000000..134cf766 Binary files /dev/null and b/res/hw/wifi6+-low.png differ diff --git a/res/hw/wifi6+-medium-pwd.png b/res/hw/wifi6+-medium-pwd.png new file mode 100644 index 00000000..4e1c908f Binary files /dev/null and b/res/hw/wifi6+-medium-pwd.png differ diff --git a/res/hw/wifi6+-medium.png b/res/hw/wifi6+-medium.png new file mode 100644 index 00000000..bb9d50dd Binary files /dev/null and b/res/hw/wifi6+-medium.png differ diff --git a/res/hw/wifi6+-none-pwd.png b/res/hw/wifi6+-none-pwd.png new file mode 100644 index 00000000..640ec001 Binary files /dev/null and b/res/hw/wifi6+-none-pwd.png differ diff --git a/res/hw/wifi6+-none.png b/res/hw/wifi6+-none.png new file mode 100644 index 00000000..fa20a4c2 Binary files /dev/null and b/res/hw/wifi6+-none.png differ diff --git a/res/hw/wifi6-full-pwd.png b/res/hw/wifi6-full-pwd.png new file mode 100644 index 00000000..427b721e Binary files /dev/null and b/res/hw/wifi6-full-pwd.png differ diff --git a/res/hw/wifi6-full.png b/res/hw/wifi6-full.png new file mode 100644 index 00000000..a4bcdcea Binary files /dev/null and b/res/hw/wifi6-full.png differ diff --git a/res/hw/wifi6-high-pwd.png b/res/hw/wifi6-high-pwd.png new file mode 100644 index 00000000..9458bb97 Binary files /dev/null and b/res/hw/wifi6-high-pwd.png differ diff --git a/res/hw/wifi6-high.png b/res/hw/wifi6-high.png new file mode 100644 index 00000000..8280cd0c Binary files /dev/null and b/res/hw/wifi6-high.png differ diff --git a/res/hw/wifi6-low-pwd.png b/res/hw/wifi6-low-pwd.png new file mode 100644 index 00000000..9b647b41 Binary files /dev/null and b/res/hw/wifi6-low-pwd.png differ diff --git a/res/hw/wifi6-low.png b/res/hw/wifi6-low.png new file mode 100644 index 00000000..5217b8dc Binary files /dev/null and b/res/hw/wifi6-low.png differ diff --git a/res/hw/wifi6-medium-pwd.png b/res/hw/wifi6-medium-pwd.png new file mode 100644 index 00000000..c157f572 Binary files /dev/null and b/res/hw/wifi6-medium-pwd.png differ diff --git a/res/hw/wifi6-medium.png b/res/hw/wifi6-medium.png new file mode 100644 index 00000000..a44f85a7 Binary files /dev/null and b/res/hw/wifi6-medium.png differ diff --git a/res/hw/wifi6-none-pwd.png b/res/hw/wifi6-none-pwd.png new file mode 100644 index 00000000..6c2973e5 Binary files /dev/null and b/res/hw/wifi6-none-pwd.png differ diff --git a/res/hw/wifi6-none.png b/res/hw/wifi6-none.png new file mode 100644 index 00000000..7d41e1ce Binary files /dev/null and b/res/hw/wifi6-none.png differ diff --git a/res/l/network-offline.png b/res/l/network-offline.png new file mode 100644 index 00000000..a288fc32 Binary files /dev/null and b/res/l/network-offline.png differ diff --git a/res/l/network-offline.svg b/res/l/network-offline.svg new file mode 100644 index 00000000..ca9dcea3 --- /dev/null +++ b/res/l/network-offline.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + diff --git a/res/l/network-online.png b/res/l/network-online.png new file mode 100644 index 00000000..b8c5fe4a Binary files /dev/null and b/res/l/network-online.png differ diff --git a/res/l/network-online.svg b/res/l/network-online.svg new file mode 100644 index 00000000..7f10bfdf --- /dev/null +++ b/res/l/network-online.svg @@ -0,0 +1 @@ +gnome-dev-ethernet32 \ No newline at end of file diff --git a/res/s/conning-a/1.png b/res/s/conning-a/1.png new file mode 100644 index 00000000..cd0fafa9 Binary files /dev/null and b/res/s/conning-a/1.png differ diff --git a/res/s/conning-a/2.png b/res/s/conning-a/2.png new file mode 100644 index 00000000..38b549a3 Binary files /dev/null and b/res/s/conning-a/2.png differ diff --git a/res/s/conning-a/3.png b/res/s/conning-a/3.png new file mode 100644 index 00000000..c002abd0 Binary files /dev/null and b/res/s/conning-a/3.png differ diff --git a/res/s/conning-a/4.png b/res/s/conning-a/4.png new file mode 100644 index 00000000..ec398d05 Binary files /dev/null and b/res/s/conning-a/4.png differ diff --git a/res/s/conning-a/5.png b/res/s/conning-a/5.png new file mode 100644 index 00000000..df58230e Binary files /dev/null and b/res/s/conning-a/5.png differ diff --git a/res/s/conning-a/6.png b/res/s/conning-a/6.png new file mode 100644 index 00000000..44fbf5d7 Binary files /dev/null and b/res/s/conning-a/6.png differ diff --git a/res/s/conning-a/7.png b/res/s/conning-a/7.png new file mode 100644 index 00000000..1dcfb6d0 Binary files /dev/null and b/res/s/conning-a/7.png differ diff --git a/res/s/conning-a/8.png b/res/s/conning-a/8.png new file mode 100644 index 00000000..01785950 Binary files /dev/null and b/res/s/conning-a/8.png differ diff --git a/res/s/conning-b/1.png b/res/s/conning-b/1.png new file mode 100644 index 00000000..31773e94 Binary files /dev/null and b/res/s/conning-b/1.png differ diff --git a/res/s/conning-b/10.png b/res/s/conning-b/10.png new file mode 100644 index 00000000..41e3c140 Binary files /dev/null and b/res/s/conning-b/10.png differ diff --git a/res/s/conning-b/11.png b/res/s/conning-b/11.png new file mode 100644 index 00000000..18920478 Binary files /dev/null and b/res/s/conning-b/11.png differ diff --git a/res/s/conning-b/12.png b/res/s/conning-b/12.png new file mode 100644 index 00000000..f5515e95 Binary files /dev/null and b/res/s/conning-b/12.png differ diff --git a/res/s/conning-b/2.png b/res/s/conning-b/2.png new file mode 100644 index 00000000..e227bb8c Binary files /dev/null and b/res/s/conning-b/2.png differ diff --git a/res/s/conning-b/3.png b/res/s/conning-b/3.png new file mode 100644 index 00000000..a1ad1bb1 Binary files /dev/null and b/res/s/conning-b/3.png differ diff --git a/res/s/conning-b/4.png b/res/s/conning-b/4.png new file mode 100644 index 00000000..db16b0d2 Binary files /dev/null and b/res/s/conning-b/4.png differ diff --git a/res/s/conning-b/5.png b/res/s/conning-b/5.png new file mode 100644 index 00000000..02dceb2e Binary files /dev/null and b/res/s/conning-b/5.png differ diff --git a/res/s/conning-b/6.png b/res/s/conning-b/6.png new file mode 100644 index 00000000..05de12c3 Binary files /dev/null and b/res/s/conning-b/6.png differ diff --git a/res/s/conning-b/7.png b/res/s/conning-b/7.png new file mode 100644 index 00000000..9f5e23fe Binary files /dev/null and b/res/s/conning-b/7.png differ diff --git a/res/s/conning-b/8.png b/res/s/conning-b/8.png new file mode 100644 index 00000000..429fa4a5 Binary files /dev/null and b/res/s/conning-b/8.png differ diff --git a/res/s/conning-b/9.png b/res/s/conning-b/9.png new file mode 100644 index 00000000..95bf53e8 Binary files /dev/null and b/res/s/conning-b/9.png differ diff --git a/res/s/conning-s/1.png b/res/s/conning-s/1.png new file mode 100644 index 00000000..69747259 Binary files /dev/null and b/res/s/conning-s/1.png differ diff --git a/res/s/conning-s/10.png b/res/s/conning-s/10.png new file mode 100644 index 00000000..964a3009 Binary files /dev/null and b/res/s/conning-s/10.png differ diff --git a/res/s/conning-s/11.png b/res/s/conning-s/11.png new file mode 100644 index 00000000..d4659b52 Binary files /dev/null and b/res/s/conning-s/11.png differ diff --git a/res/s/conning-s/12.png b/res/s/conning-s/12.png new file mode 100644 index 00000000..cb0272e3 Binary files /dev/null and b/res/s/conning-s/12.png differ diff --git a/res/s/conning-s/1x/1.png b/res/s/conning-s/1x/1.png new file mode 100644 index 00000000..258bd704 Binary files /dev/null and b/res/s/conning-s/1x/1.png differ diff --git a/res/s/conning-s/1x/10.png b/res/s/conning-s/1x/10.png new file mode 100644 index 00000000..88398b80 Binary files /dev/null and b/res/s/conning-s/1x/10.png differ diff --git a/res/s/conning-s/1x/11.png b/res/s/conning-s/1x/11.png new file mode 100644 index 00000000..7157960f Binary files /dev/null and b/res/s/conning-s/1x/11.png differ diff --git a/res/s/conning-s/1x/12.png b/res/s/conning-s/1x/12.png new file mode 100644 index 00000000..60b88e98 Binary files /dev/null and b/res/s/conning-s/1x/12.png differ diff --git a/res/s/conning-s/1x/2.png b/res/s/conning-s/1x/2.png new file mode 100644 index 00000000..45eedb2b Binary files /dev/null and b/res/s/conning-s/1x/2.png differ diff --git a/res/s/conning-s/1x/3.png b/res/s/conning-s/1x/3.png new file mode 100644 index 00000000..96cfdad7 Binary files /dev/null and b/res/s/conning-s/1x/3.png differ diff --git a/res/s/conning-s/1x/4.png b/res/s/conning-s/1x/4.png new file mode 100644 index 00000000..c8a9a982 Binary files /dev/null and b/res/s/conning-s/1x/4.png differ diff --git a/res/s/conning-s/1x/5.png b/res/s/conning-s/1x/5.png new file mode 100644 index 00000000..0595e6b9 Binary files /dev/null and b/res/s/conning-s/1x/5.png differ diff --git a/res/s/conning-s/1x/6.png b/res/s/conning-s/1x/6.png new file mode 100644 index 00000000..274f5a8f Binary files /dev/null and b/res/s/conning-s/1x/6.png differ diff --git a/res/s/conning-s/1x/7.png b/res/s/conning-s/1x/7.png new file mode 100644 index 00000000..c49a271f Binary files /dev/null and b/res/s/conning-s/1x/7.png differ diff --git a/res/s/conning-s/1x/8.png b/res/s/conning-s/1x/8.png new file mode 100644 index 00000000..94946d6a Binary files /dev/null and b/res/s/conning-s/1x/8.png differ diff --git a/res/s/conning-s/1x/9.png b/res/s/conning-s/1x/9.png new file mode 100644 index 00000000..87f74199 Binary files /dev/null and b/res/s/conning-s/1x/9.png differ diff --git a/res/s/conning-s/2.png b/res/s/conning-s/2.png new file mode 100644 index 00000000..eb6a4a41 Binary files /dev/null and b/res/s/conning-s/2.png differ diff --git a/res/s/conning-s/3.png b/res/s/conning-s/3.png new file mode 100644 index 00000000..f985e8cf Binary files /dev/null and b/res/s/conning-s/3.png differ diff --git a/res/s/conning-s/4.png b/res/s/conning-s/4.png new file mode 100644 index 00000000..e8645dc4 Binary files /dev/null and b/res/s/conning-s/4.png differ diff --git a/res/s/conning-s/5.png b/res/s/conning-s/5.png new file mode 100644 index 00000000..089e6710 Binary files /dev/null and b/res/s/conning-s/5.png differ diff --git a/res/s/conning-s/6.png b/res/s/conning-s/6.png new file mode 100644 index 00000000..aee7edf2 Binary files /dev/null and b/res/s/conning-s/6.png differ diff --git a/res/s/conning-s/7.png b/res/s/conning-s/7.png new file mode 100644 index 00000000..914deea1 Binary files /dev/null and b/res/s/conning-s/7.png differ diff --git a/res/s/conning-s/8.png b/res/s/conning-s/8.png new file mode 100644 index 00000000..b3de2879 Binary files /dev/null and b/res/s/conning-s/8.png differ diff --git a/res/s/conning-s/9.png b/res/s/conning-s/9.png new file mode 100644 index 00000000..ffbdb739 Binary files /dev/null and b/res/s/conning-s/9.png differ diff --git a/res/s/rescan/1.png b/res/s/rescan/1.png new file mode 100644 index 00000000..19c4f777 Binary files /dev/null and b/res/s/rescan/1.png differ diff --git a/res/s/rescan/10.png b/res/s/rescan/10.png new file mode 100644 index 00000000..2b4c501f Binary files /dev/null and b/res/s/rescan/10.png differ diff --git a/res/s/rescan/11.png b/res/s/rescan/11.png new file mode 100644 index 00000000..c43ee8ce Binary files /dev/null and b/res/s/rescan/11.png differ diff --git a/res/s/rescan/12.png b/res/s/rescan/12.png new file mode 100644 index 00000000..b3c08bed Binary files /dev/null and b/res/s/rescan/12.png differ diff --git a/res/s/rescan/2.png b/res/s/rescan/2.png new file mode 100644 index 00000000..40628922 Binary files /dev/null and b/res/s/rescan/2.png differ diff --git a/res/s/rescan/3.png b/res/s/rescan/3.png new file mode 100644 index 00000000..d6a64bc5 Binary files /dev/null and b/res/s/rescan/3.png differ diff --git a/res/s/rescan/4.png b/res/s/rescan/4.png new file mode 100644 index 00000000..f92092f0 Binary files /dev/null and b/res/s/rescan/4.png differ diff --git a/res/s/rescan/5.png b/res/s/rescan/5.png new file mode 100644 index 00000000..279fd345 Binary files /dev/null and b/res/s/rescan/5.png differ diff --git a/res/s/rescan/6.png b/res/s/rescan/6.png new file mode 100644 index 00000000..cea2f895 Binary files /dev/null and b/res/s/rescan/6.png differ diff --git a/res/s/rescan/7.png b/res/s/rescan/7.png new file mode 100644 index 00000000..f9b384aa Binary files /dev/null and b/res/s/rescan/7.png differ diff --git a/res/s/rescan/8.png b/res/s/rescan/8.png new file mode 100644 index 00000000..3930bef0 Binary files /dev/null and b/res/s/rescan/8.png differ diff --git a/res/s/rescan/9.png b/res/s/rescan/9.png new file mode 100644 index 00000000..bd22fa1b Binary files /dev/null and b/res/s/rescan/9.png differ diff --git a/res/w/wifi-full-pwd.png b/res/w/wifi-full-pwd.png new file mode 100644 index 00000000..065f7f8e Binary files /dev/null and b/res/w/wifi-full-pwd.png differ diff --git a/res/w/wifi-full.png b/res/w/wifi-full.png new file mode 100644 index 00000000..48024d04 Binary files /dev/null and b/res/w/wifi-full.png differ diff --git a/res/w/wifi-high-pwd.png b/res/w/wifi-high-pwd.png new file mode 100644 index 00000000..81a4d11e Binary files /dev/null and b/res/w/wifi-high-pwd.png differ diff --git a/res/w/wifi-high.png b/res/w/wifi-high.png new file mode 100644 index 00000000..3ec53052 Binary files /dev/null and b/res/w/wifi-high.png differ diff --git a/res/w/wifi-low-pwd.png b/res/w/wifi-low-pwd.png new file mode 100644 index 00000000..784ad1b2 Binary files /dev/null and b/res/w/wifi-low-pwd.png differ diff --git a/res/w/wifi-low.png b/res/w/wifi-low.png new file mode 100644 index 00000000..3fe8bded Binary files /dev/null and b/res/w/wifi-low.png differ diff --git a/res/w/wifi-medium-pwd.png b/res/w/wifi-medium-pwd.png new file mode 100644 index 00000000..221fdbc1 Binary files /dev/null and b/res/w/wifi-medium-pwd.png differ diff --git a/res/w/wifi-medium.png b/res/w/wifi-medium.png new file mode 100644 index 00000000..3b1683f3 Binary files /dev/null and b/res/w/wifi-medium.png differ diff --git a/res/w/wifi-none-pwd.png b/res/w/wifi-none-pwd.png new file mode 100644 index 00000000..109f19ee Binary files /dev/null and b/res/w/wifi-none-pwd.png differ diff --git a/res/w/wifi-none.png b/res/w/wifi-none.png new file mode 100644 index 00000000..0a3bdd14 Binary files /dev/null and b/res/w/wifi-none.png differ diff --git a/res/w/wifi6+-full-pwd.png b/res/w/wifi6+-full-pwd.png new file mode 100644 index 00000000..b4498c0c Binary files /dev/null and b/res/w/wifi6+-full-pwd.png differ diff --git a/res/w/wifi6+-full.png b/res/w/wifi6+-full.png new file mode 100644 index 00000000..4c3867e4 Binary files /dev/null and b/res/w/wifi6+-full.png differ diff --git a/res/w/wifi6+-high-pwd.png b/res/w/wifi6+-high-pwd.png new file mode 100644 index 00000000..a6d9456b Binary files /dev/null and b/res/w/wifi6+-high-pwd.png differ diff --git a/res/w/wifi6+-high.png b/res/w/wifi6+-high.png new file mode 100644 index 00000000..5144960f Binary files /dev/null and b/res/w/wifi6+-high.png differ diff --git a/res/w/wifi6+-low-pwd.png b/res/w/wifi6+-low-pwd.png new file mode 100644 index 00000000..802a3668 Binary files /dev/null and b/res/w/wifi6+-low-pwd.png differ diff --git a/res/w/wifi6+-low.png b/res/w/wifi6+-low.png new file mode 100644 index 00000000..f7e4a96d Binary files /dev/null and b/res/w/wifi6+-low.png differ diff --git a/res/w/wifi6+-medium-pwd.png b/res/w/wifi6+-medium-pwd.png new file mode 100644 index 00000000..68f47cf3 Binary files /dev/null and b/res/w/wifi6+-medium-pwd.png differ diff --git a/res/w/wifi6+-medium.png b/res/w/wifi6+-medium.png new file mode 100644 index 00000000..ae79551c Binary files /dev/null and b/res/w/wifi6+-medium.png differ diff --git a/res/w/wifi6+-meidum-pwd.png b/res/w/wifi6+-meidum-pwd.png new file mode 100644 index 00000000..5d64fddc Binary files /dev/null and b/res/w/wifi6+-meidum-pwd.png differ diff --git a/res/w/wifi6+-none.png b/res/w/wifi6+-none.png new file mode 100644 index 00000000..20a30ee0 Binary files /dev/null and b/res/w/wifi6+-none.png differ diff --git a/res/w/wifi6-full-pwd.png b/res/w/wifi6-full-pwd.png new file mode 100644 index 00000000..cd21cd7e Binary files /dev/null and b/res/w/wifi6-full-pwd.png differ diff --git a/res/w/wifi6-full.png b/res/w/wifi6-full.png new file mode 100644 index 00000000..becdaa07 Binary files /dev/null and b/res/w/wifi6-full.png differ diff --git a/res/w/wifi6-high-pwd.png b/res/w/wifi6-high-pwd.png new file mode 100644 index 00000000..cf650101 Binary files /dev/null and b/res/w/wifi6-high-pwd.png differ diff --git a/res/w/wifi6-high.png b/res/w/wifi6-high.png new file mode 100644 index 00000000..a8d64899 Binary files /dev/null and b/res/w/wifi6-high.png differ diff --git a/res/w/wifi6-low-pwd.png b/res/w/wifi6-low-pwd.png new file mode 100644 index 00000000..b58198bf Binary files /dev/null and b/res/w/wifi6-low-pwd.png differ diff --git a/res/w/wifi6-low.png b/res/w/wifi6-low.png new file mode 100644 index 00000000..5217b8dc Binary files /dev/null and b/res/w/wifi6-low.png differ diff --git a/res/w/wifi6-medium-pwd.png b/res/w/wifi6-medium-pwd.png new file mode 100644 index 00000000..b713c4ec Binary files /dev/null and b/res/w/wifi6-medium-pwd.png differ diff --git a/res/w/wifi6-medium.png b/res/w/wifi6-medium.png new file mode 100644 index 00000000..135b1817 Binary files /dev/null and b/res/w/wifi6-medium.png differ diff --git a/res/w/wifi6-none-pwd.png b/res/w/wifi6-none-pwd.png new file mode 100644 index 00000000..aee1b42a Binary files /dev/null and b/res/w/wifi6-none-pwd.png differ diff --git a/res/w/wifi6-none.png b/res/w/wifi6-none.png new file mode 100644 index 00000000..c4563c20 Binary files /dev/null and b/res/w/wifi6-none.png differ diff --git a/res/x/control.svg b/res/x/control.svg new file mode 100644 index 00000000..a64182b7 --- /dev/null +++ b/res/x/control.svg @@ -0,0 +1,15 @@ + + + + +画板 1 + + + diff --git a/res/x/fly-mode-off.svg b/res/x/fly-mode-off.svg new file mode 100644 index 00000000..408b7b07 --- /dev/null +++ b/res/x/fly-mode-off.svg @@ -0,0 +1,19 @@ + + + + +画板 1 + + + + + diff --git a/res/x/fly-mode-on.svg b/res/x/fly-mode-on.svg new file mode 100644 index 00000000..9f5e543b --- /dev/null +++ b/res/x/fly-mode-on.svg @@ -0,0 +1,14 @@ + + + + +画板 1 + + diff --git a/res/x/hot-spot-off.svg b/res/x/hot-spot-off.svg new file mode 100644 index 00000000..cf39cadb --- /dev/null +++ b/res/x/hot-spot-off.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + diff --git a/res/x/hot-spot-on.svg b/res/x/hot-spot-on.svg new file mode 100644 index 00000000..2041db9d --- /dev/null +++ b/res/x/hot-spot-on.svg @@ -0,0 +1,17 @@ + + + + + + + + + + diff --git a/res/x/load-down.png b/res/x/load-down.png new file mode 100644 index 00000000..a96298ac Binary files /dev/null and b/res/x/load-down.png differ diff --git a/res/x/load-up.png b/res/x/load-up.png new file mode 100644 index 00000000..e5ec581b Binary files /dev/null and b/res/x/load-up.png differ diff --git a/res/x/net-list-bg.svg b/res/x/net-list-bg.svg new file mode 100644 index 00000000..c17c1fd8 --- /dev/null +++ b/res/x/net-list-bg.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/res/x/setup.png b/res/x/setup.png new file mode 100644 index 00000000..fe242f89 Binary files /dev/null and b/res/x/setup.png differ diff --git a/res/x/wifi-list-bg.svg b/res/x/wifi-list-bg.svg new file mode 100644 index 00000000..43f18664 --- /dev/null +++ b/res/x/wifi-list-bg.svg @@ -0,0 +1,15 @@ + + + + +画板 1 + + + + + + + diff --git a/src/backend/backend.pri b/src/backend/backend.pri new file mode 100644 index 00000000..feb4853f --- /dev/null +++ b/src/backend/backend.pri @@ -0,0 +1,22 @@ +INCLUDEPATH += $$PWD +include(hotspot/hotspot.pri) +include(dbus-interface/dbus-interface.pri) + +HEADERS += \ + $$PWD/dbusadaptor.h \ + $$PWD/kylinarping.h \ + $$PWD/kylinipv4arping.h \ + $$PWD/kylinipv6arping.h \ + $$PWD/sysdbusregister.h \ + $$PWD/utils.h \ + $$PWD/wifi-auth-thread.h + +SOURCES += \ + $$PWD/dbusadaptor.cpp \ + $$PWD/kylinipv4arping.cpp \ + $$PWD/kylinipv6arping.cpp \ + $$PWD/sysdbusregister.cpp \ + $$PWD/utils.cpp \ + $$PWD/wifi-auth-thread.cpp + +DISTFILES += diff --git a/src/backend/dbus-interface/dbus-interface.pri b/src/backend/dbus-interface/dbus-interface.pri new file mode 100644 index 00000000..056901df --- /dev/null +++ b/src/backend/dbus-interface/dbus-interface.pri @@ -0,0 +1,46 @@ +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/gsystem-local-alloc.h \ + $$PWD/kyenterpricesettinginfo.h \ + $$PWD/kylinactiveconnectresource.h \ + $$PWD/kylinagent.h \ + $$PWD/kylinagentinterface.h \ + $$PWD/kylinapconnectitem.h \ + $$PWD/kylinbluetoothconnectitem.h \ + $$PWD/kylinconnectitem.h \ + $$PWD/kylinconnectoperation.h \ + $$PWD/kylinconnectresource.h \ + $$PWD/kylinconnectsetting.h \ + $$PWD/kylinnetworkdeviceresource.h \ + $$PWD/kylinnetworkresourcemanager.h \ + $$PWD/kylinutil.h \ + $$PWD/kylinvpnconnectitem.h \ + $$PWD/kylinvpnrequest.h \ + $$PWD/kylinwiredconnectoperation.h \ + $$PWD/kywirelessconnectoperation.h \ + $$PWD/kywirelessnetitem.h \ + $$PWD/kywirelessnetresource.h \ + $$PWD/nm-macros-internal.h + +SOURCES += \ + $$PWD/kyenterpricesettinginfo.cpp \ + $$PWD/kylinactiveconnectresource.cpp \ + $$PWD/kylinagent.c \ + $$PWD/kylinagentinterface.c \ + $$PWD/kylinapconnectitem.cpp \ + $$PWD/kylinbluetoothconnectitem.cpp \ + $$PWD/kylinconnectitem.cpp \ + $$PWD/kylinconnectoperation.cpp \ + $$PWD/kylinconnectresource.cpp \ + $$PWD/kylinconnectsetting.cpp \ + $$PWD/kylinnetworkdeviceresource.cpp \ + $$PWD/kylinnetworkresourcemanager.cpp \ + $$PWD/kylinutil.cpp \ + $$PWD/kylinvpnconnectitem.cpp \ + $$PWD/kylinvpnrequest.c \ + $$PWD/kylinwiredconnectoperation.cpp \ + $$PWD/kywirelessconnectoperation.cpp \ + $$PWD/kywirelessnetitem.cpp \ + $$PWD/kywirelessnetresource.cpp + diff --git a/src/backend/dbus-interface/gsystem-local-alloc.h b/src/backend/dbus-interface/gsystem-local-alloc.h new file mode 100644 index 00000000..b74cc0aa --- /dev/null +++ b/src/backend/dbus-interface/gsystem-local-alloc.h @@ -0,0 +1,188 @@ +#ifndef __GSYSTEM_LOCAL_ALLOC_H__ +#define __GSYSTEM_LOCAL_ALLOC_H__ + +#include + +G_BEGIN_DECLS + +#define GS_DEFINE_CLEANUP_FUNCTION(Type, name, func) \ + static inline void name (void *v) \ + { \ + func (*(Type*)v); \ + } + +#define GS_DEFINE_CLEANUP_FUNCTION0(Type, name, func) \ + static inline void name (void *v) \ + { \ + if (*(Type*)v) \ + func (*(Type*)v); \ + } + +/* These functions shouldn't be invoked directly; + * they are stubs that: + * 1) Take a pointer to the location (typically itself a pointer). + * 2) Provide %NULL-safety where it doesn't exist already (e.g. g_object_unref) + */ + +/** + * gs_free: + * + * Call g_free() on a variable location when it goes out of scope. + */ +#define gs_free __attribute__ ((cleanup(gs_local_free))) +GS_DEFINE_CLEANUP_FUNCTION(void*, gs_local_free, g_free) + +/** + * gs_unref_object: + * + * Call g_object_unref() on a variable location when it goes out of + * scope. Note that unlike g_object_unref(), the variable may be + * %NULL. + */ +#define gs_unref_object __attribute__ ((cleanup(gs_local_obj_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GObject*, gs_local_obj_unref, g_object_unref) + +/** + * gs_unref_variant: + * + * Call g_variant_unref() on a variable location when it goes out of + * scope. Note that unlike g_variant_unref(), the variable may be + * %NULL. + */ +#define gs_unref_variant __attribute__ ((cleanup(gs_local_variant_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GVariant*, gs_local_variant_unref, g_variant_unref) + +/** + * gs_free_variant_iter: + * + * Call g_variant_iter_free() on a variable location when it goes out of + * scope. + */ +#define gs_free_variant_iter __attribute__ ((cleanup(gs_local_variant_iter_free))) +GS_DEFINE_CLEANUP_FUNCTION0(GVariantIter*, gs_local_variant_iter_free, g_variant_iter_free) + +/** + * gs_free_variant_builder: + * + * Call g_variant_builder_unref() on a variable location when it goes out of + * scope. + */ +#define gs_unref_variant_builder __attribute__ ((cleanup(gs_local_variant_builder_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GVariantBuilder*, gs_local_variant_builder_unref, g_variant_builder_unref) + +/** + * gs_unref_array: + * + * Call g_array_unref() on a variable location when it goes out of + * scope. Note that unlike g_array_unref(), the variable may be + * %NULL. + + */ +#define gs_unref_array __attribute__ ((cleanup(gs_local_array_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GArray*, gs_local_array_unref, g_array_unref) + +/** + * gs_unref_ptrarray: + * + * Call g_ptr_array_unref() on a variable location when it goes out of + * scope. Note that unlike g_ptr_array_unref(), the variable may be + * %NULL. + + */ +#define gs_unref_ptrarray __attribute__ ((cleanup(gs_local_ptrarray_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GPtrArray*, gs_local_ptrarray_unref, g_ptr_array_unref) + +/** + * gs_unref_hashtable: + * + * Call g_hash_table_unref() on a variable location when it goes out + * of scope. Note that unlike g_hash_table_unref(), the variable may + * be %NULL. + */ +#define gs_unref_hashtable __attribute__ ((cleanup(gs_local_hashtable_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GHashTable*, gs_local_hashtable_unref, g_hash_table_unref) + +/** + * gs_free_list: + * + * Call g_list_free() on a variable location when it goes out + * of scope. + */ +#define gs_free_list __attribute__ ((cleanup(gs_local_free_list))) +GS_DEFINE_CLEANUP_FUNCTION(GList*, gs_local_free_list, g_list_free) + +/** + * gs_free_slist: + * + * Call g_slist_free() on a variable location when it goes out + * of scope. + */ +#define gs_free_slist __attribute__ ((cleanup(gs_local_free_slist))) +GS_DEFINE_CLEANUP_FUNCTION(GSList*, gs_local_free_slist, g_slist_free) + +/** + * gs_free_checksum: + * + * Call g_checksum_free() on a variable location when it goes out + * of scope. Note that unlike g_checksum_free(), the variable may + * be %NULL. + */ +#define gs_free_checksum __attribute__ ((cleanup(gs_local_checksum_free))) +GS_DEFINE_CLEANUP_FUNCTION0(GChecksum*, gs_local_checksum_free, g_checksum_free) + +/** + * gs_unref_bytes: + * + * Call g_bytes_unref() on a variable location when it goes out + * of scope. Note that unlike g_bytes_unref(), the variable may + * be %NULL. + */ +#define gs_unref_bytes __attribute__ ((cleanup(gs_local_bytes_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GBytes*, gs_local_bytes_unref, g_bytes_unref) + +/** + * gs_strfreev: + * + * Call g_strfreev() on a variable location when it goes out of scope. + */ +#define gs_strfreev __attribute__ ((cleanup(gs_local_strfreev))) +GS_DEFINE_CLEANUP_FUNCTION(char**, gs_local_strfreev, g_strfreev) + +/** + * gs_free_error: + * + * Call g_error_free() on a variable location when it goes out of scope. + */ +#define gs_free_error __attribute__ ((cleanup(gs_local_free_error))) +GS_DEFINE_CLEANUP_FUNCTION0(GError*, gs_local_free_error, g_error_free) + +/** + * gs_unref_keyfile: + * + * Call g_key_file_unref() on a variable location when it goes out of scope. + */ +#define gs_unref_keyfile __attribute__ ((cleanup(gs_local_keyfile_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GKeyFile*, gs_local_keyfile_unref, g_key_file_unref) + +static inline void +gs_cleanup_close_fdp (int *fdp) +{ + int fd; + + g_assert (fdp); + + fd = *fdp; + if (fd != -1) + (void) close (fd); +} + +/** + * gs_fd_close: + * + * Call close() on a variable location when it goes out of scope. + */ +#define gs_fd_close __attribute__((cleanup(gs_cleanup_close_fdp))) + +G_END_DECLS + +#endif diff --git a/src/backend/dbus-interface/kyenterpricesettinginfo.cpp b/src/backend/dbus-interface/kyenterpricesettinginfo.cpp new file mode 100644 index 00000000..8bff2062 --- /dev/null +++ b/src/backend/dbus-interface/kyenterpricesettinginfo.cpp @@ -0,0 +1,176 @@ +#include "kyenterpricesettinginfo.h" + +void assembleEapMethodTlsSettings(NetworkManager::ConnectionSettings::Ptr connSettingPtr, const KyEapMethodTlsInfo &info) +{ + NetworkManager::Security8021xSetting::Ptr wifi_8021x_sett + = connSettingPtr->setting(NetworkManager::Setting::Security8021x).dynamicCast(); + + QList list; + list.append(NetworkManager::Security8021xSetting::EapMethod::EapMethodTls); + wifi_8021x_sett->setInitialized(true); + wifi_8021x_sett->setEapMethods(list); + wifi_8021x_sett->setIdentity(info.identity); + if (!info.domain.isEmpty()){ + wifi_8021x_sett->setDomainSuffixMatch(info.domain); + } + if (info.bNeedCa) { + QByteArray caCerEndWithNull("file://" + info.caCertPath.toUtf8() + '\0'); + wifi_8021x_sett->setCaCertificate(caCerEndWithNull); + } else { + QByteArray caCerEndWithNull(""); + wifi_8021x_sett->setCaCertificate(caCerEndWithNull); + } + QByteArray cliCertEndWithNull("file://" + info.clientCertPath.toUtf8() + '\0'); + wifi_8021x_sett->setClientCertificate(cliCertEndWithNull); + QByteArray cliPriKeyEndWithNull("file://" + info.clientPrivateKey.toUtf8() + '\0'); + wifi_8021x_sett->setPrivateKey(cliPriKeyEndWithNull); + wifi_8021x_sett->setPrivateKeyPassword(info.clientPrivateKeyPWD); + wifi_8021x_sett->setPrivateKeyPasswordFlags(info.m_privateKeyPWDFlag); + + NetworkManager::WirelessSecuritySetting::Ptr security_sett + = connSettingPtr->setting(NetworkManager::Setting::WirelessSecurity).dynamicCast(); + security_sett->setInitialized(true); + security_sett->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaEap); + + return; +} + +void assembleEapMethodPeapSettings(NetworkManager::ConnectionSettings::Ptr connSettingPtr, const KyEapMethodPeapInfo &info) +{ + qDebug() << "assembleEapMethodPeapSettings"; + + NetworkManager::Security8021xSetting::Ptr wifi_8021x_sett + = connSettingPtr->setting(NetworkManager::Setting::Security8021x).dynamicCast(); + + QList list; + list.append(NetworkManager::Security8021xSetting::EapMethod::EapMethodPeap); + wifi_8021x_sett->setInitialized(true); + wifi_8021x_sett->setEapMethods(list); + wifi_8021x_sett->setPhase2AuthMethod((NetworkManager::Security8021xSetting::AuthMethod)info.phase2AuthMethod); + wifi_8021x_sett->setIdentity(info.userName); + wifi_8021x_sett->setPassword(info.userPWD); + wifi_8021x_sett->setPasswordFlags(info.m_passwdFlag); + + + NetworkManager::WirelessSecuritySetting::Ptr security_sett + = connSettingPtr->setting(NetworkManager::Setting::WirelessSecurity).dynamicCast(); + security_sett->setInitialized(true); + security_sett->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaEap); + return; +} + +void assembleEapMethodTtlsSettings(NetworkManager::ConnectionSettings::Ptr connSettingPtr, const KyEapMethodTtlsInfo &info) +{ + + NetworkManager::Security8021xSetting::Ptr wifi_8021x_sett + = connSettingPtr->setting(NetworkManager::Setting::Security8021x).dynamicCast(); + + QList list; + list.append(NetworkManager::Security8021xSetting::EapMethod::EapMethodTtls); + wifi_8021x_sett->setInitialized(true); + wifi_8021x_sett->setEapMethods(list); + if (info.authType == KyTtlsAuthMethod::AUTH_EAP) + { + wifi_8021x_sett->setPhase2AuthEapMethod((NetworkManager::Security8021xSetting::AuthEapMethod)info.authEapMethod);//gtc md5 mschapv2 otp tls + } else if (info.authType == KyTtlsAuthMethod::AUTH_NO_EAP) + { + wifi_8021x_sett->setPhase2AuthMethod((NetworkManager::Security8021xSetting::AuthMethod)info.authNoEapMethod);//chap md5 mschapv2 pap gtc mschap otp tls + } + wifi_8021x_sett->setIdentity(info.userName); + wifi_8021x_sett->setPassword(info.userPWD); + wifi_8021x_sett->setPasswordFlags(info.m_passwdFlag); + + NetworkManager::WirelessSecuritySetting::Ptr security_sett + = connSettingPtr->setting(NetworkManager::Setting::WirelessSecurity).dynamicCast(); + security_sett->setInitialized(true); + security_sett->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaEap); + return; +} + + +void modifyEapMethodTlsSettings(NetworkManager::ConnectionSettings::Ptr connSettingPtr, const KyEapMethodTlsInfo &tlsInfo) +{ + NetworkManager::Security8021xSetting::Ptr setting = connSettingPtr->setting(NetworkManager::Setting::Security8021x).dynamicCast(); + setting->setInitialized(true); + + QList list; + list.append(NetworkManager::Security8021xSetting::EapMethod::EapMethodTls); + setting->setEapMethods(list); + setting->setIdentity(tlsInfo.identity); + if(!tlsInfo.domain.isEmpty()) + { + setting->setDomainSuffixMatch(tlsInfo.domain); + } + if (tlsInfo.bNeedCa) + { + QByteArray caCerEndWithNull("file://" + tlsInfo.caCertPath.toUtf8() + '\0'); + setting->setCaCertificate(caCerEndWithNull); + } else { + QByteArray caCerEndWithNull(""); + setting->setCaCertificate(caCerEndWithNull); + } + + QByteArray cliCertEndWithNull("file://" + tlsInfo.clientCertPath.toUtf8() + '\0'); + setting->setClientCertificate(cliCertEndWithNull); + QByteArray cliPriKeyEndWithNull("file://" + tlsInfo.clientPrivateKey.toUtf8() + '\0'); + setting->setPrivateKey(cliPriKeyEndWithNull); + setting->setPrivateKeyPasswordFlags(tlsInfo.m_privateKeyPWDFlag); + if(tlsInfo.bChanged) + { + setting->setPrivateKeyPassword(tlsInfo.clientPrivateKeyPWD); + } + return; +} + +void modifyEapMethodPeapSettings(NetworkManager::ConnectionSettings::Ptr connSettingPtr, const KyEapMethodPeapInfo &peapInfo) +{ + qDebug() << "assembleEapMethodPeapSettings"; + + NetworkManager::Security8021xSetting::Ptr wifi_8021x_sett + = connSettingPtr->setting(NetworkManager::Setting::Security8021x).dynamicCast(); + wifi_8021x_sett->setInitialized(true); + + QList list; + list.append(NetworkManager::Security8021xSetting::EapMethod::EapMethodPeap); + wifi_8021x_sett->setEapMethods(list); + wifi_8021x_sett->setPhase2AuthMethod((NetworkManager::Security8021xSetting::AuthMethod)peapInfo.phase2AuthMethod); + wifi_8021x_sett->setIdentity(peapInfo.userName); + if(peapInfo.bChanged) + { + wifi_8021x_sett->setPassword(peapInfo.userPWD); + } + wifi_8021x_sett->setPasswordFlags(peapInfo.m_passwdFlag); + + QByteArray caCerEndWithNull(""); + wifi_8021x_sett->setCaCertificate(caCerEndWithNull); + + return; +} + +void modifyEapMethodTtlsSettings(NetworkManager::ConnectionSettings::Ptr connSettingPtr, const KyEapMethodTtlsInfo &ttlsInfo) +{ + NetworkManager::Security8021xSetting::Ptr wifi_8021x_sett + = connSettingPtr->setting(NetworkManager::Setting::Security8021x).dynamicCast(); + + QList list; + list.append(NetworkManager::Security8021xSetting::EapMethod::EapMethodTtls); + wifi_8021x_sett->setInitialized(true); + wifi_8021x_sett->setEapMethods(list); + if (ttlsInfo.authType == KyTtlsAuthMethod::AUTH_EAP) + { + wifi_8021x_sett->setPhase2AuthEapMethod((NetworkManager::Security8021xSetting::AuthEapMethod)ttlsInfo.authEapMethod);//gtc md5 mschapv2 otp tls + } else if (ttlsInfo.authType == KyTtlsAuthMethod::AUTH_NO_EAP) + { + wifi_8021x_sett->setPhase2AuthMethod((NetworkManager::Security8021xSetting::AuthMethod)ttlsInfo.authNoEapMethod);//chap md5 mschapv2 pap gtc mschap otp tls + } + wifi_8021x_sett->setIdentity(ttlsInfo.userName); + if(ttlsInfo.bChanged) + { + wifi_8021x_sett->setPassword(ttlsInfo.userPWD); + } + wifi_8021x_sett->setPasswordFlags(ttlsInfo.m_passwdFlag); + + QByteArray caCerEndWithNull(""); + wifi_8021x_sett->setCaCertificate(caCerEndWithNull); + return; +} diff --git a/src/backend/dbus-interface/kyenterpricesettinginfo.h b/src/backend/dbus-interface/kyenterpricesettinginfo.h new file mode 100644 index 00000000..01c8b29e --- /dev/null +++ b/src/backend/dbus-interface/kyenterpricesettinginfo.h @@ -0,0 +1,146 @@ +#ifndef KYENTERPRICESETTINGINFO_H +#define KYENTERPRICESETTINGINFO_H + +#include +#include + +#include "kylinnetworkresourcemanager.h" +#include + +enum KyEapMethodType { + TLS = 0, + PEAP, + TTLS, +}; + +class KyEapMethodTlsInfo +{ +public: + QString identity; + QString domain; + QString devIfaceName; + QString caCertPath; + bool bNeedCa; + QString clientCertPath; + QString clientPrivateKey; + QString clientPrivateKeyPWD; + NetworkManager::Setting::SecretFlags m_privateKeyPWDFlag; + // only valid when update + bool bChanged; + + inline bool operator == (const KyEapMethodTlsInfo& info) const + { + if (this->identity == info.identity + && this->domain == info.domain +// && this->devIfaceName == info.devIfaceName + && this->caCertPath == info.caCertPath + && this->bNeedCa == info.bNeedCa + && this->clientCertPath == info.clientCertPath + && this->clientPrivateKey == info.clientPrivateKey + && this->clientPrivateKeyPWD == info.clientPrivateKeyPWD + && this->m_privateKeyPWDFlag == info.m_privateKeyPWDFlag) { + return true; + } else { + return false; + } + } +}; + +typedef enum { + KyAuthEapMethodUnknown = 0, + KyAuthEapMethodMd5, + KyAuthEapMethodMschapv2, + KyAuthEapMethodOtp, + KyAuthEapMethodGtc, + KyAuthEapMethodTls +} KyEapMethodAuth; + +typedef enum{ + KyAuthMethodUnknown = 0, + KyAuthMethodPap, + KyAuthMethodChap, + KyAuthMethodMschap, + KyAuthMethodMschapv2, + KyAuthMethodGtc, + KyAuthMethodOtp, + KyAuthMethodMd5, + KyAuthMethodTls +} KyNoEapMethodAuth; + + +class KyEapMethodPeapInfo +{ +public: + KyNoEapMethodAuth phase2AuthMethod; + QString userName; + QString userPWD; + NetworkManager::Setting::SecretFlags m_passwdFlag; + // only valid when update + bool bChanged; + + inline bool operator == (const KyEapMethodPeapInfo& info) const + { + if (this->phase2AuthMethod == info.phase2AuthMethod + && this->userName == info.userName + && this->userPWD == info.userPWD + && this->m_passwdFlag == info.m_passwdFlag) { + return true; + } else { + return false; + } + } +}; + +enum KyTtlsAuthMethod +{ + AUTH_EAP, + AUTH_NO_EAP +}; + +class KyEapMethodTtlsInfo +{ +public: + KyTtlsAuthMethod authType; + KyEapMethodAuth authEapMethod; + KyNoEapMethodAuth authNoEapMethod; + QString userName; + QString userPWD; + NetworkManager::Setting::SecretFlags m_passwdFlag; + // only valid when update + bool bChanged; + + inline bool operator == (const KyEapMethodTtlsInfo& info) const + { + if (this->authType == info.authType) { + if (authType == AUTH_EAP) { + if (this->authEapMethod == info.authEapMethod + && this ->userName == info.userName + && this->userPWD == info.userPWD + && this->m_passwdFlag == info.m_passwdFlag) { + return true; + } + } else { + if (authType == AUTH_EAP) { + if (this->authNoEapMethod == info.authNoEapMethod + && this ->userName == info.userName + && this->userPWD == info.userPWD + && this->m_passwdFlag == info.m_passwdFlag) { + return true; + } + } + } + + } + return false; + } +}; + +void assembleEapMethodTlsSettings(NetworkManager::ConnectionSettings::Ptr connSettingPtr, const KyEapMethodTlsInfo &tlsInfo); +void assembleEapMethodPeapSettings(NetworkManager::ConnectionSettings::Ptr connSettingPtr, const KyEapMethodPeapInfo &peapInfo); +void assembleEapMethodTtlsSettings(NetworkManager::ConnectionSettings::Ptr connSettingPtr, const KyEapMethodTtlsInfo &ttlsInfo); + +void modifyEapMethodTlsSettings(NetworkManager::ConnectionSettings::Ptr connSettingPtr, const KyEapMethodTlsInfo &tlsInfo); +void modifyEapMethodPeapSettings(NetworkManager::ConnectionSettings::Ptr connSettingPtr, const KyEapMethodPeapInfo &peapInfo); +void modifyEapMethodTtlsSettings(NetworkManager::ConnectionSettings::Ptr connSettingPtr, const KyEapMethodTtlsInfo &ttlsInfo); + +#endif // KYENTERPRICESETTINGINFO_H diff --git a/src/backend/dbus-interface/kylinactiveconnectresource.cpp b/src/backend/dbus-interface/kylinactiveconnectresource.cpp new file mode 100644 index 00000000..e56de5ac --- /dev/null +++ b/src/backend/dbus-interface/kylinactiveconnectresource.cpp @@ -0,0 +1,717 @@ +#include "kylinutil.h" +#include "kylinactiveconnectresource.h" +#include "kywirelessconnectoperation.h" + +#include +#include +#include + +#define LOG_FLAG "[KyActiveConnectResourse]" + +KyActiveConnectResourse::KyActiveConnectResourse(QObject *parent) : QObject(parent) +{ + m_networkResourceInstance = KyNetworkResourceManager::getInstance(); + m_networkdevice = new KyNetworkDeviceResourse(); + + connect(m_networkResourceInstance, &KyNetworkResourceManager::activeConnectionRemove, + this, &KyActiveConnectResourse::activeConnectRemove); + connect(m_networkResourceInstance, &KyNetworkResourceManager::activeConnectStateChangeReason, + this, &KyActiveConnectResourse::stateChangeReason); + connect(m_networkResourceInstance, &KyNetworkResourceManager::vpnActiveConnectStateChangeReason, + this, &KyActiveConnectResourse::vpnConnectChangeReason); +} + +KyActiveConnectResourse::~KyActiveConnectResourse() +{ + m_networkResourceInstance = nullptr; + if (nullptr != m_networkdevice) { + delete m_networkdevice; + m_networkdevice = nullptr; + } +} + +KyConnectItem *KyActiveConnectResourse::getActiveConnectionItem(NetworkManager::ActiveConnection::Ptr activeConnectPtr) +{ + qDebug()<<"[KyActiveConnectResourse]"<<"get active connect item"; + + if (nullptr == activeConnectPtr) { + qWarning()<<"[KyActiveConnectResourse]"<<"the active connect is empty"; + return nullptr; + } + + if (NetworkManager::ActiveConnection::State::Activated != activeConnectPtr->state()) { + qWarning()<<"[KyActiveConnectResourse]"<<"the active connect is not activated" + <<"connect name:"<connection()->name() + <<"connect state"<< activeConnectPtr->state(); + return nullptr; + } + + KyConnectItem *activeConnectItem = new KyConnectItem(); + activeConnectItem->m_connectUuid = activeConnectPtr->uuid(); + + NetworkManager::Connection::Ptr connectPtr = activeConnectPtr->connection(); + activeConnectItem->m_connectName = connectPtr->name(); + activeConnectItem->m_connectPath = connectPtr->path(); + + activeConnectItem->m_connectState = NetworkManager::ActiveConnection::State::Activated; + + return activeConnectItem; +} + +KyConnectItem *KyActiveConnectResourse::getActiveConnectionByUuid(QString connectUuid) +{ + NetworkManager::ActiveConnection::List activeConnectList; + activeConnectList.clear(); + activeConnectList = m_networkResourceInstance->getActiveConnectList(); + + if (activeConnectList.empty()) { + qWarning()<<"[KyActiveConnectResourse]"<<"the active connect list is empty"; + return nullptr; + } + //可能存在已无效的ActiveConnection,所以使用uuid遍历处理需要满足device不为空且ActiveConnection状态为已连接 + NetworkManager::ActiveConnection::Ptr activeConnectPtr = nullptr; + KyConnectItem *activeConnectItem = nullptr; + bool isFind = false; + for (int index = 0; index < activeConnectList.size(); index++) { + activeConnectPtr = activeConnectList.at(index); + if (activeConnectPtr.isNull()) { + continue; + } + + if (connectUuid != activeConnectPtr->uuid()) { + continue; + } + + activeConnectItem = getActiveConnectionItem(activeConnectPtr); + + if (nullptr == activeConnectItem || activeConnectPtr->devices().isEmpty()) { + continue; + } else { + isFind = true; + } + } + + if (!isFind) { + return nullptr; + } + + QString ifaceUni = activeConnectPtr->devices().at(0); + NetworkManager::Device:: Ptr devicePtr = + m_networkResourceInstance->findDeviceUni(ifaceUni); + activeConnectItem->m_ifaceName = devicePtr->interfaceName(); + activeConnectItem->m_itemType = activeConnectPtr->type(); + + return activeConnectItem; +} + +KyConnectItem *KyActiveConnectResourse::getActiveConnectionByUuid(QString connectUuid, + QString deviceName) +{ + NetworkManager::ActiveConnection::Ptr activeConnectPtr = + m_networkResourceInstance->getActiveConnect(connectUuid); + + if (nullptr == activeConnectPtr) { + qWarning()<< "[KyActiveConnectResourse]" <<"it can not find connect "<< connectUuid; + return nullptr; + } + + QStringList interfaces = activeConnectPtr->devices(); + for (int index = 0; index < interfaces.size(); ++index) { + QString ifaceUni = interfaces.at(index); + NetworkManager::Device:: Ptr devicePtr = + m_networkResourceInstance->findDeviceUni(ifaceUni); + if (devicePtr.isNull()) { + continue; + } + + if (devicePtr->interfaceName() == deviceName) { + KyConnectItem *activeConnectItem = + getActiveConnectionItem(activeConnectPtr); + if (nullptr == activeConnectItem) { + return nullptr; + } + activeConnectItem->m_ifaceName = deviceName; + activeConnectItem->m_itemType = activeConnectPtr->type(); + return activeConnectItem; + } + } + + return nullptr; +} + +void KyActiveConnectResourse::getActiveConnectionList(QString deviceName, + NetworkManager::ConnectionSettings::ConnectionType connectionType, + QList &activeConnectItemList) +{ + qDebug()<<"[KyActiveConnectResourse]"<<"get activate connect for device" + << deviceName <<"connect type:"<getActiveConnectList(); + + if (activeConnectList.empty()) { + qWarning()<<"[KyActiveConnectResourse]"<<"the active connect list is empty"; + return; + } + + NetworkManager::ActiveConnection::Ptr activeConnectPtr = nullptr; + for (int index = 0; index < activeConnectList.size(); index++) { + activeConnectPtr = activeConnectList.at(index); + if (activeConnectPtr.isNull()) { + continue; + } + + if (connectionType != activeConnectPtr->type()) { + qDebug()<<"[KyActiveConnectResourse]" <<"the connect type " << activeConnectPtr->type() + <<"connect name" << activeConnectPtr->connection()->name(); + continue; + } + + QStringList interfaces = activeConnectPtr->devices(); + for (int index = 0; index < interfaces.size(); ++index) { + QString ifaceUni = interfaces.at(index); + NetworkManager::Device:: Ptr devicePtr = + m_networkResourceInstance->findDeviceUni(ifaceUni); + if (devicePtr->interfaceName() == deviceName) { + KyConnectItem *activeConnectItem = + getActiveConnectionItem(activeConnectPtr); + if (nullptr != activeConnectItem) { + activeConnectItem->m_ifaceName = deviceName; + activeConnectItem->m_itemType = connectionType; + activeConnectItemList << activeConnectItem; + //activeConnectItem->dumpInfo(); + } + + activeConnectPtr = nullptr; + break; + } + } + } + + return; +} + +#if 0 +void KyActiveConnectResourse::getWiredActivateConnect(QList &wiredActiveConnectItemList) +{ + int index = 0; + NetworkManager::ActiveConnection::List activeConnectList; + qDebug()<<"[KyActiveConnectResourse]"<<"get wired activate connect"; + + activeConnectList.clear(); + activeConnectList = m_networkResourceInstance->getActiveConnectList(); + + if (activeConnectList.empty()) { + qWarning()<<"[KyActiveConnectResourse]"<<"the active connect list is empty"; + return; + } + + NetworkManager::ActiveConnection::Ptr activeConnectPtr = nullptr; + for (index = 0; index < activeConnectList.size(); index++) { + activeConnectPtr = activeConnectList.at(index); + if (NetworkManager::ConnectionSettings::ConnectionType::Wired + != activeConnectPtr->type()) { + continue; + } + + KyWiredConnectItem *activeConnectItem = + getWiredActiveConnectItem(activeConnectPtr); + if (nullptr != activeConnectItem) { + wiredActiveConnectItemList << activeConnectItem; + activeConnectItem->dumpInfo(); + } + + activeConnectPtr = nullptr; + } + + return; +} + +KyWiredConnectItem *KyActiveConnectResourse::getWiredActiveConnectItem(NetworkManager::ActiveConnection::Ptr activeConnectPtr) +{ + qDebug()<<"[KyActiveConnectResourse]"<<"get active connect item"; + + if (nullptr == activeConnectPtr) { + qWarning()<<"[KyActiveConnectResourse]"<<"the active connect is empty"; + return nullptr; + } + + if (NetworkManager::ActiveConnection::State::Activated != activeConnectPtr->state()) { + qWarning()<<"[KyActiveConnectResourse]"<<"the active connect is not activated" + <connection()->name() << activeConnectPtr->state(); + return nullptr; + } + + KyWiredConnectItem *wiredItem = new KyWiredConnectItem(); + NetworkManager::Connection::Ptr connectPtr = activeConnectPtr->connection(); + NetworkManager::ConnectionSettings::Ptr settingPtr = connectPtr->settings(); + + wiredItem->m_connectName = connectPtr->name(); + qDebug() <<"[KyActiveConnectResourse]"<< "connect uuid" << connectPtr->uuid() + << "active connect uuid" << activeConnectPtr->uuid(); + wiredItem->m_connectUuid = activeConnectPtr->uuid(); + wiredItem->m_ifaceName = settingPtr->interfaceName(); + + + getActiveConnectIp(activeConnectPtr, wiredItem->m_ipv4, wiredItem->m_ipv6); + + m_networkdevice->getWiredHardwareInfo(settingPtr->interfaceName(), wiredItem); + + wiredItem->m_state = NetworkManager::ActiveConnection::State::Activated; + //wiredItem->m_itemType; + + return wiredItem; +} + +#endif + +void KyActiveConnectResourse::getActiveConnectIpInfo( + const QString &connectUuid, + QString &ipv4Address, + QString &ipv6Address) +{ + NetworkManager::ActiveConnection::Ptr activeConnectPtr = + m_networkResourceInstance->getActiveConnect(connectUuid); + + if (activeConnectPtr.isNull()) { + qWarning()<< "[KyActiveConnectResourse]" <<"it can not find connect "<< connectUuid; + return; + } + + getActiveConnectIp(activeConnectPtr, ipv4Address, ipv6Address); + + return; +} + +void KyActiveConnectResourse::getActiveConnectIp( + NetworkManager::ActiveConnection::Ptr activeConnectPtr, + QString &ipv4Address, + QString &ipv6Address) +{ + qDebug()<<"[KyActiveConnectResourse]"<<"get active connect ip info"; + + NetworkManager::IpConfig ipv4Config =activeConnectPtr->ipV4Config(); + if (ipv4Config.isValid()) { + if (!ipv4Config.addresses().isEmpty()) { + NetworkManager::IpAddress address = ipv4Config.addresses().at(0); + ipv4Address = address.ip().toString(); + } else { + qWarning()<<"[KyActiveConnectResourse]"<<"the ipv4 address is empty."; + } + } else { + qWarning()<<"[KyActiveConnectResourse]"<<"ipv4 config is not valid"; + } + + NetworkManager::IpConfig ipv6Config =activeConnectPtr->ipV6Config(); + if (ipv6Config.isValid()) { + if (!ipv6Config.addresses().isEmpty()) { + NetworkManager::IpAddress address = ipv6Config.addresses().at(0); + ipv6Address = address.ip().toString(); + } else { + qWarning()<<"[KyActiveConnectResourse]"<<"ipv6 address is empty"; + } + } else { + qWarning()<<"[KyActiveConnectResourse]"<<"ipv6 config is not valid"; + } + + return; +} + +void KyActiveConnectResourse::getActiveConnectDnsInfo( + const QString &connectUuid, + QList &ipv4Dns, + QList &ipv6Dns) +{ + NetworkManager::ActiveConnection::Ptr activeConnectPtr = + m_networkResourceInstance->getActiveConnect(connectUuid); + if (activeConnectPtr.isNull()) { + qWarning()<< "[KyActiveConnectResourse]" <<"it can not find connect "<< connectUuid; + return; + } + + getActiveConnectDns(activeConnectPtr, ipv4Dns, ipv6Dns); + + return; +} + +void KyActiveConnectResourse::getActiveConnectDns( + NetworkManager::ActiveConnection::Ptr activeConnectPtr, + QList &ipv4Dns, + QList &ipv6Dns) +{ + qDebug()<<"[KyActiveConnectResourse]"<<"get active connect nameservice info"; + + NetworkManager::IpConfig ipv4Config = activeConnectPtr->ipV4Config(); + if (ipv4Config.isValid()) { + ipv4Dns = ipv4Config.nameservers(); + } else { + qWarning()<<"[KyActiveConnectResourse]"<<"ipv4 config is not valid"; + } + + NetworkManager::IpConfig ipv6Config =activeConnectPtr->ipV6Config(); + if (ipv6Config.isValid()) { + ipv6Dns = ipv6Config.nameservers(); + } else { + qWarning()<<"[KyActiveConnectResourse]"<<"ipv6 config is not valid"; + } + + return; +} + +KyVpnConnectItem *KyActiveConnectResourse::getVpnActiveConnectItem(NetworkManager::ActiveConnection::Ptr activeConnectPtr) +{ + qDebug()<<"[KyActiveConnectResourse]"<<"get vpn active connect item"; + + if (nullptr == activeConnectPtr) { + qWarning()<<"[KyActiveConnectResourse]"<<"get vpn active connect failed, the active connect is empty"; + return nullptr; + } + + if (NetworkManager::ActiveConnection::State::Activated != activeConnectPtr->state()) { + qWarning()<<"[KyActiveConnectResourse]"<<"the active connect is not activated" + <connection()->name() << activeConnectPtr->state(); + return nullptr; + } + + KyVpnConnectItem *vpnItem = new KyVpnConnectItem(); + NetworkManager::Connection::Ptr connectPtr = activeConnectPtr->connection(); + vpnItem->m_vpnName = connectPtr->name(); + + vpnItem->m_vpnUuid = activeConnectPtr->uuid(); + + NetworkManager::ConnectionSettings::Ptr settingsPtr = connectPtr->settings(); + NetworkManager::VpnSetting::Ptr vpnSetting = settingsPtr->setting(NetworkManager::Setting::Vpn).dynamicCast(); + NMStringMap vpnDataMap = vpnSetting->data(); + if (vpnDataMap.isEmpty()) { + qWarning()<<"[KyActiveConnectResourse]"<<"get vpn connection Data failed, the data is empty"; + } else { + vpnItem->m_vpnGateWay = vpnDataMap["gateway"]; + vpnItem->m_vpnUser = vpnDataMap["user"]; + if ( "yes" == vpnDataMap["require-mppe"]) { + vpnItem->m_vpnMppe = true; + } else { + vpnItem->m_vpnMppe = false; + qDebug()<<"[KyActiveConnectResourse]"<<"vpn mppe required:"<< vpnDataMap["require-mppe"]; + } + } + + getActiveConnectIp(activeConnectPtr, vpnItem->m_vpnIpv4Address, vpnItem->m_vpnIpv6Address); + + NetworkManager::VpnConnection *p_vpnConnect = qobject_cast(activeConnectPtr.data()); + vpnItem->m_vpnState = p_vpnConnect->state(); + + return vpnItem; +} + +void KyActiveConnectResourse::getVpnActivateConnect(QList &vpnActiveConnectItemList) +{ + int index = 0; + NetworkManager::ActiveConnection::List activeConnectList; + + activeConnectList.clear(); + activeConnectList = m_networkResourceInstance->getActiveConnectList(); + + if (activeConnectList.empty()) { + qWarning()<<"[KyActiveConnectResourse]"<<"get vpn active connect failed, the active connect list is empty"; + return; + } + + NetworkManager::ActiveConnection::Ptr activeConnectPtr = nullptr; + for (index = 0; index < activeConnectList.size(); index++) { + activeConnectPtr = activeConnectList.at(index); + if (activeConnectPtr.isNull()) { + continue; + } + + if (!activeConnectPtr->vpn()) { + continue; + } + + KyVpnConnectItem *activeConnectItem = + getVpnActiveConnectItem(activeConnectPtr); + if (nullptr != activeConnectItem) { + vpnActiveConnectItemList << activeConnectItem; + } + + activeConnectPtr = nullptr; + } + + return; +} + +KyBluetoothConnectItem *KyActiveConnectResourse::getBtActiveConnectItem(NetworkManager::ActiveConnection::Ptr activeConnectPtr) +{ + qDebug()<<"[KyActiveConnectResourse]"<<"get bluetooth active connect item"; + + if (nullptr == activeConnectPtr) { + qWarning()<<"[KyActiveConnectResourse]"<<"get bluetooth item failed, the active connect is empty"; + return nullptr; + } + + if (NetworkManager::ActiveConnection::State::Activated != activeConnectPtr->state()) { + qWarning()<<"[KyActiveConnectResourse]"<<"get bluetooth item failed, the active connect is not activated" + <connection()->name() << activeConnectPtr->state(); + return nullptr; + } + + KyBluetoothConnectItem *bluetoothItem = new KyBluetoothConnectItem(); + NetworkManager::Connection::Ptr connectPtr = activeConnectPtr->connection(); + + bluetoothItem->m_connectName = connectPtr->name(); + bluetoothItem->m_connectUuid = activeConnectPtr->uuid(); + bluetoothItem->m_state = NetworkManager::ActiveConnection::State::Activated; + + getActiveConnectIp(activeConnectPtr, bluetoothItem->m_ipv4Address, bluetoothItem->m_ipv6Address); + + NetworkManager::ConnectionSettings::Ptr settingPtr = connectPtr->settings(); + NetworkManager::BluetoothSetting::Ptr bluetoothSetting = + settingPtr->setting(NetworkManager::Setting::Bluetooth).dynamicCast(); + bluetoothItem->m_deviceAddress = bluetoothSetting->bluetoothAddress(); + QByteArray btAddrArray = bluetoothSetting->bluetoothAddress(); + for (int index = 0; index < btAddrArray.size(); ++index) { + qDebug("bt address %d %s", index, btAddrArray[index]); + } + qDebug()<<"bluetooth device address"<m_deviceAddress; + //wiredItem->m_itemType; + + return bluetoothItem; +} + +void KyActiveConnectResourse::getBtActivateConnect(QList &btActiveConnectItemList) +{ + int index = 0; + NetworkManager::ActiveConnection::List activeConnectList; + + activeConnectList.clear(); + activeConnectList = m_networkResourceInstance->getActiveConnectList(); + + if (activeConnectList.empty()) { + qWarning()<<"[KyActiveConnectResourse]"<<"get bluetooth active connect failed, the active connect list is empty"; + return; + } + + NetworkManager::ActiveConnection::Ptr activeConnectPtr = nullptr; + for (index = 0; index < activeConnectList.size(); index++) { + activeConnectPtr = activeConnectList.at(index); + if (activeConnectPtr.isNull()) { + continue; + } + + if (NetworkManager::ConnectionSettings::ConnectionType::Bluetooth + != activeConnectPtr->type()) { + continue; + } + + KyBluetoothConnectItem *activeConnectItem = getBtActiveConnectItem(activeConnectPtr); + if (nullptr != activeConnectItem) { + btActiveConnectItemList << activeConnectItem; + } + + activeConnectPtr = nullptr; + } + + return; +} + +KyApConnectItem *KyActiveConnectResourse::getApActiveConnectItem(NetworkManager::ActiveConnection::Ptr activeConnectPtr) +{ + qDebug()<<"[KyActiveConnectResourse]"<<"get wireless ap active connect item"; + + if (nullptr == activeConnectPtr) { + qWarning()<<"[KyActiveConnectResourse]"<<"get wireless ap item failed, the active connect is empty"; + return nullptr; + } + + if (NetworkManager::ActiveConnection::State::Activated != activeConnectPtr->state()) { + qWarning()<<"[KyActiveConnectResourse]"<<"get ap item failed, the active connect is not activated" + <connection()->name() << activeConnectPtr->state(); + return nullptr; + } + + NetworkManager::Connection::Ptr connectPtr = activeConnectPtr->connection(); + NetworkManager::ConnectionSettings::Ptr settingPtr = connectPtr->settings(); + NetworkManager::WirelessSetting::Ptr wirelessSetting + = settingPtr->setting(NetworkManager::Setting::Wireless).dynamicCast(); + if (NetworkManager::WirelessSetting::NetworkMode::Ap + != wirelessSetting->mode()) { + qDebug() << "[KyActiveConnectResourse]" <<"get ap item failed, the active connect mode is not ap."; + return nullptr; + } + + KyApConnectItem *apConnectItem = new KyApConnectItem(); + apConnectItem->m_connectName = connectPtr->name(); + apConnectItem->m_connectUuid = activeConnectPtr->uuid(); + apConnectItem->m_ifaceName = settingPtr->interfaceName(); + + QByteArray rawSsid = wirelessSetting->ssid(); + apConnectItem->m_connectSsid = getSsidFromByteArray(rawSsid); + + + KyWirelessConnectOperation wirelessOperation; + apConnectItem->m_password = wirelessOperation.getPsk(apConnectItem->m_connectUuid); + + return apConnectItem; +} + +void KyActiveConnectResourse::getApActivateConnect(QList &apConnectItemList) +{ + int index = 0; + NetworkManager::ActiveConnection::List activeConnectList; + + activeConnectList.clear(); + activeConnectList = m_networkResourceInstance->getActiveConnectList(); + + if (activeConnectList.empty()) { + qWarning()<<"[KyActiveConnectResourse]" + <<"get ap active connect failed, the active connect list is empty"; + return; + } + + NetworkManager::ActiveConnection::Ptr activeConnectPtr = nullptr; + for (index = 0; index < activeConnectList.size(); index++) { + activeConnectPtr = activeConnectList.at(index); + if (activeConnectPtr.isNull()) { + continue; + } + + if (NetworkManager::ConnectionSettings::ConnectionType::Wireless + != activeConnectPtr->type()) { + continue; + } + + KyApConnectItem *apConnectItem = getApActiveConnectItem(activeConnectPtr); + if (nullptr != apConnectItem) { + apConnectItemList << apConnectItem; + } + + activeConnectPtr = nullptr; + } + + return; +} + +QString KyActiveConnectResourse::getDeviceOfActivateConnect(QString conUuid) +{ + QString deviceName = ""; + + NetworkManager::ActiveConnection::Ptr activeConnectPtr = + m_networkResourceInstance->getActiveConnect(conUuid); + + if (nullptr == activeConnectPtr) { + qWarning()<< "[KyActiveConnectResourse]" <<"it can not find connect "<< conUuid; + return deviceName; + } + + QStringList interfaces = activeConnectPtr->devices(); + if (interfaces.isEmpty()) { + qWarning()<< LOG_FLAG << "get device of active connection failed."; + return deviceName; + } + + QString ifaceUni = interfaces.at(0); + NetworkManager::Device:: Ptr devicePtr = + m_networkResourceInstance->findDeviceUni(ifaceUni); + deviceName = devicePtr->interfaceName(); + + return deviceName; +} + +bool KyActiveConnectResourse::connectionIsVirtual(QString uuid) +{ + NetworkManager::ActiveConnection::Ptr activeConnectPtr = + m_networkResourceInstance->getActiveConnect(uuid); + + if (activeConnectPtr.isNull()) { + qWarning()<< LOG_FLAG << "check connection virtual is failed."; + return false; + } + + QStringList interfaces = activeConnectPtr->devices(); + if (interfaces.isEmpty()) { + qWarning()<< LOG_FLAG << "active connection get device failed."; + return false; + } + + QString ifaceUni = interfaces.at(0); + NetworkManager::Device:: Ptr devicePtr = + m_networkResourceInstance->findDeviceUni(ifaceUni); + if (devicePtr.isNull()) { + return false; + } + + return !m_networkdevice->deviceIsWired(devicePtr->interfaceName()); +} + +bool KyActiveConnectResourse::wiredConnectIsActived() +{ + int index = 0; + NetworkManager::ActiveConnection::List activeConnectList; + + activeConnectList.clear(); + activeConnectList = m_networkResourceInstance->getActiveConnectList(); + + if (activeConnectList.empty()) { + qWarning()<<"[KyActiveConnectResourse]" + <<"get active connect failed, the active connect list is empty"; + return false; + } + + NetworkManager::ActiveConnection::Ptr activeConnectPtr = nullptr; + for (index = 0; index < activeConnectList.size(); index++) { + activeConnectPtr = activeConnectList.at(index); + if (activeConnectPtr.isNull()) { + continue; + } + + if (NetworkManager::ConnectionSettings::ConnectionType::Wired + != activeConnectPtr->type()) { + continue; + } + + if (connectionIsVirtual(activeConnectPtr->uuid())) { + continue; + } + + if (activeConnectPtr->state() == NetworkManager::ActiveConnection::State::Activated) { + return true; + } + } + + return false; +} + +bool KyActiveConnectResourse::checkWirelessStatus(NetworkManager::ActiveConnection::State state) +{ + int index = 0; + NetworkManager::ActiveConnection::List activeConnectList; + + activeConnectList.clear(); + activeConnectList = m_networkResourceInstance->getActiveConnectList(); + + if (activeConnectList.empty()) { + qWarning()<<"[KyActiveConnectResourse]" + <<"get active connect failed, the active connect list is empty"; + return false; + } + + NetworkManager::ActiveConnection::Ptr activeConnectPtr = nullptr; + for (index = 0; index < activeConnectList.size(); index++) { + activeConnectPtr = activeConnectList.at(index); + if (activeConnectPtr.isNull()) { + continue; + } + + if (NetworkManager::ConnectionSettings::ConnectionType::Wireless + != activeConnectPtr->type()) { + continue; + } + + if (activeConnectPtr->state() == state) { + return true; + } + } + + return false; + +} diff --git a/src/backend/dbus-interface/kylinactiveconnectresource.h b/src/backend/dbus-interface/kylinactiveconnectresource.h new file mode 100644 index 00000000..db781917 --- /dev/null +++ b/src/backend/dbus-interface/kylinactiveconnectresource.h @@ -0,0 +1,74 @@ +#ifndef KYLINACTIVECONNECTRESOURCE_H +#define KYLINACTIVECONNECTRESOURCE_H + +#include +#include "kylinnetworkresourcemanager.h" +#include "kylinconnectitem.h" +#include "kylinnetworkdeviceresource.h" +#include "kylinvpnconnectitem.h" +#include "kylinbluetoothconnectitem.h" +#include "kylinapconnectitem.h" + +class KyActiveConnectResourse : public QObject +{ + Q_OBJECT +public: + explicit KyActiveConnectResourse(QObject *parent = nullptr); + ~KyActiveConnectResourse(); + +public: + KyConnectItem *getActiveConnectionByUuid(QString connectUuid); + KyConnectItem *getActiveConnectionByUuid(QString connectUuid, QString deviceName); + void getActiveConnectionList(QString deviceName, + NetworkManager::ConnectionSettings::ConnectionType connectionType, + QList &connectItemList); + void getActiveConnectIpInfo(const QString &uuid, + QString &ipv4Address, + QString &ipv6Address); + void getActiveConnectDnsInfo(const QString &uuid, + QList &ipv4Dns, + QList &ipv6Dns); + + //void getWiredActivateConnect(QList &wiredActiveConnectItemList); + void getVpnActivateConnect(QList &vpnActiveConnectItemList); + void getBtActivateConnect(QList &btActiveConnectItemList); + + void getApActivateConnect(QList &apConnectItemList); + + QString getDeviceOfActivateConnect(QString conUuid); + + bool connectionIsVirtual(QString uuid); + bool wiredConnectIsActived(); + bool checkWirelessStatus(NetworkManager::ActiveConnection::State state); + +private: + void getActiveConnectIp(NetworkManager::ActiveConnection::Ptr activeConnectPtr, + QString &ipv4Address, + QString &ipv6Address); + void getActiveConnectDns(NetworkManager::ActiveConnection::Ptr activeConnectPtr, + QList &ipv4Dns, + QList &ipv6Dns); + + KyConnectItem *getActiveConnectionItem(NetworkManager::ActiveConnection::Ptr activeConnectPtr); + + // KyWiredConnectItem *getWiredActiveConnectItem(NetworkManager::ActiveConnection::Ptr activeConnectPtr); + KyVpnConnectItem *getVpnActiveConnectItem(NetworkManager::ActiveConnection::Ptr activeConnectPtr); + KyBluetoothConnectItem *getBtActiveConnectItem(NetworkManager::ActiveConnection::Ptr activeConnectPtr); + KyApConnectItem *getApActiveConnectItem(NetworkManager::ActiveConnection::Ptr activeConnectPtr); + +signals: + void activeConnectAdd(QString activeConnectUuid); + void updateActiveConnect(QString activeConnectUuid); + void activeConnectRemove(QString activeConnectUuid); + void stateChangeReason(QString uuid, + NetworkManager::ActiveConnection::State state, + NetworkManager::ActiveConnection::Reason reason); + void vpnConnectChangeReason(QString uuid, + NetworkManager::VpnConnection::State state, + NetworkManager::VpnConnection::StateChangeReason reason); + +private: + KyNetworkResourceManager *m_networkResourceInstance = nullptr; + KyNetworkDeviceResourse *m_networkdevice = nullptr; +}; +#endif // KYLINACTIVECONNECTRESOURCE_H diff --git a/src/backend/dbus-interface/kylinagent.c b/src/backend/dbus-interface/kylinagent.c new file mode 100644 index 00000000..393d9fc4 --- /dev/null +++ b/src/backend/dbus-interface/kylinagent.c @@ -0,0 +1,836 @@ +#include "kylinagent.h" +#include + +#define KEYRING_UUID_TAG "connection-uuid" +#define KEYRING_SN_TAG "setting-name" +#define KEYRING_SK_TAG "setting-key" + +static const SecretSchema network_manager_secret_schema = { + "org.freedesktop.NetworkManager.Connection", + SECRET_SCHEMA_DONT_MATCH_NAME, + { + { KEYRING_UUID_TAG, SECRET_SCHEMA_ATTRIBUTE_STRING }, + { KEYRING_SN_TAG, SECRET_SCHEMA_ATTRIBUTE_STRING }, + { KEYRING_SK_TAG, SECRET_SCHEMA_ATTRIBUTE_STRING }, + { NULL, 0 }, + } +}; + +G_DEFINE_TYPE (AppletAgent, applet_agent, NM_TYPE_SECRET_AGENT_OLD); + +#define APPLET_AGENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), APPLET_TYPE_AGENT, AppletAgentPrivate)) + +typedef struct { + GHashTable *requests; + gboolean vpn_only; + + gboolean disposed; +} AppletAgentPrivate; + +enum { + GET_SECRETS, + CANCEL_SECRETS, + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL] = { 0 }; + + +/*******************************************************/ + +typedef struct { + guint id; + + NMSecretAgentOld *agent; + NMConnection *connection; + char *path; + char *setting_name; + char **hints; + guint32 flags; + NMSecretAgentOldGetSecretsFunc get_callback; + NMSecretAgentOldSaveSecretsFunc save_callback; + NMSecretAgentOldDeleteSecretsFunc delete_callback; + gpointer callback_data; + + GCancellable *cancellable; + gint keyring_calls; +} Request; + +static Request * +request_new (NMSecretAgentOld *agent, + NMConnection *connection, + const char *connection_path, + const char *setting_name, + const char **hints, + guint32 flags, + NMSecretAgentOldGetSecretsFunc get_callback, + NMSecretAgentOldSaveSecretsFunc save_callback, + NMSecretAgentOldDeleteSecretsFunc delete_callback, + gpointer callback_data) +{ + static guint32 counter = 1; + Request *r; + + r = g_slice_new0 (Request); + r->id = counter++; + r->agent = agent; + r->connection = g_object_ref (connection); + r->path = g_strdup (connection_path); + r->setting_name = g_strdup (setting_name); + if (hints) + r->hints = g_strdupv ((gchar **) hints); + r->flags = flags; + r->get_callback = get_callback; + r->save_callback = save_callback; + r->delete_callback = delete_callback; + r->callback_data = callback_data; + r->cancellable = g_cancellable_new (); + return r; +} + +static void +request_free (Request *r) +{ + if (!g_cancellable_is_cancelled (r->cancellable)) + g_hash_table_remove (APPLET_AGENT_GET_PRIVATE (r->agent)->requests, GUINT_TO_POINTER (r->id)); + + /* By the time the request is freed, all keyring calls should be completed */ + g_warn_if_fail (r->keyring_calls == 0); + + g_object_unref (r->connection); + g_free (r->path); + g_free (r->setting_name); + g_strfreev (r->hints); + g_object_unref (r->cancellable); + memset (r, 0, sizeof (*r)); + g_slice_free (Request, r); +} + +/*******************************************************/ + +static void +get_save_cb (NMSecretAgentOld *agent, + NMConnection *connection, + GError *error, + gpointer user_data) +{ + /* Ignored */ +} + +static void +get_secrets_cb (AppletAgent *self, + GVariant *secrets, + GError *error, + gpointer user_data) +{ + Request *r = user_data; + + /* 'secrets' shouldn't be valid if there was an error */ + if (error) { + g_warn_if_fail (secrets == NULL); + secrets = NULL; + } + + if (!g_cancellable_is_cancelled (r->cancellable)) { + /* Save updated secrets as long as user-interaction was allowed; otherwise + * we'd be saving secrets we just pulled out of the keyring which is somewhat + * redundant. + */ + if (secrets && (r->flags != NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE)) { + NMConnection *dupl; + GVariantIter iter; + const char *setting_name; + + /* Copy the existing connection and update its secrets */ + dupl = nm_simple_connection_new_clone (r->connection); + g_variant_iter_init (&iter, secrets); + while (g_variant_iter_next (&iter, "{&s@a{sv}}", (gpointer) &setting_name, NULL)) + nm_connection_update_secrets (dupl, setting_name, secrets, NULL); + + /* And save updated secrets to the keyring */ + nm_secret_agent_old_save_secrets (NM_SECRET_AGENT_OLD (self), dupl, get_save_cb, NULL); + g_object_unref (dupl); + } + + r->get_callback (NM_SECRET_AGENT_OLD (r->agent), r->connection, secrets, error, r->callback_data); + } + request_free (r); +} + +static void +ask_for_secrets (Request *r) +{ + /* Ask the applet to get some secrets for us */ + g_signal_emit (r->agent, + signals[GET_SECRETS], + 0, + GUINT_TO_POINTER (r->id), + r->connection, + r->setting_name, + r->hints, + r->flags, + get_secrets_cb, + r); +} + +static void +check_always_ask_cb (NMSetting *setting, + const char *key, + const GValue *value, + GParamFlags flags, + gpointer user_data) +{ + gboolean *always_ask = user_data; + NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; + + if (flags & NM_SETTING_PARAM_SECRET) { + if (nm_setting_get_secret_flags (setting, key, &secret_flags, NULL)) { + if (secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) + *always_ask = TRUE; + } + } +} + +static gboolean +has_always_ask (NMSetting *setting) +{ + gboolean always_ask = FALSE; + + nm_setting_enumerate_values (setting, check_always_ask_cb, &always_ask); + return always_ask; +} + +static gboolean +is_connection_always_ask (NMConnection *connection) +{ + NMSettingConnection *s_con; + const char *ctype; + NMSetting *setting; + + /* For the given connection type, check if the secrets for that connection + * are always-ask or not. + */ + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + ctype = nm_setting_connection_get_connection_type (s_con); + + setting = nm_connection_get_setting_by_name (connection, ctype); + g_return_val_if_fail (setting != NULL, FALSE); + + if (has_always_ask (setting)) + return TRUE; + + /* Try type-specific settings too; be a bit paranoid and only consider + * secrets from settings relevant to the connection type. + */ + if (NM_IS_SETTING_WIRELESS (setting)) { + setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + if (setting && has_always_ask (setting)) + return TRUE; + setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); + if (setting && has_always_ask (setting)) + return TRUE; + } else if (NM_IS_SETTING_WIRED (setting)) { + setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE); + if (setting && has_always_ask (setting)) + return TRUE; + setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); + if (setting && has_always_ask (setting)) + return TRUE; + } + + return FALSE; +} + +static void +keyring_find_secrets_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + Request *r = user_data; + GError *error = NULL; + GError *search_error = NULL; + const char *connection_id = NULL; + GVariantBuilder builder_setting, builder_connection; + GVariant *settings = NULL; + GList *list = NULL; + GList *iter; + gboolean hint_found = FALSE, ask = FALSE; + + r->keyring_calls--; + if (g_cancellable_is_cancelled (r->cancellable)) { + /* Callback already called by NM or dispose */ + request_free (r); + return; + } + + list = secret_service_search_finish (NULL, result, &search_error); + connection_id = nm_connection_get_id (r->connection); + + if (g_error_matches (search_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + error = g_error_new_literal (NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_USER_CANCELED, + "The secrets request was canceled by the user"); + g_error_free (search_error); + goto done; + } else if ( (r->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION) + && g_error_matches (search_error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) { + /* If the connection always asks for secrets, tolerate + * keyring service not being present. */ + g_clear_error (&search_error); + } else if (search_error) { + error = g_error_new (NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + "%s.%d - failed to read secrets from keyring (%s)", + __FILE__, __LINE__, search_error->message); + g_error_free (search_error); + goto done; + } + + /* Only ask if we're allowed to, so that eg a connection editor which + * requests secrets for its UI, for a connection which doesn't have any + * secrets yet, doesn't trigger the applet secrets dialog. + */ + if ( (r->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION) + && g_list_length (list) == 0) { + g_message ("No keyring secrets found for %s/%s; asking user.", connection_id, r->setting_name); + ask_for_secrets (r); + return; + } + + g_variant_builder_init (&builder_setting, NM_VARIANT_TYPE_SETTING); + + /* Extract the secrets from the list of matching keyring items */ + for (iter = list; iter != NULL; iter = g_list_next (iter)) { + SecretItem *item = iter->data; + SecretValue *secret; + const char *key_name; + GHashTable *attributes; + + secret = secret_item_get_secret (item); + if (secret) { + attributes = secret_item_get_attributes (item); + key_name = g_hash_table_lookup (attributes, KEYRING_SK_TAG); + if (!key_name) { + g_hash_table_unref (attributes); + secret_value_unref (secret); + continue; + } + + g_variant_builder_add (&builder_setting, "{sv}", key_name, + g_variant_new_string (secret_value_get (secret, NULL))); + + /* See if this property matches a given hint */ + if (r->hints && r->hints[0]) { + if (!g_strcmp0 (r->hints[0], key_name) || !g_strcmp0 (r->hints[1], key_name)) + hint_found = TRUE; + } + + g_hash_table_unref (attributes); + secret_value_unref (secret); + break; + } + } + + /* If there were hints, and none of the hints were returned by the keyring, + * get some new secrets. + */ + if (r->flags) { + if (r->hints && r->hints[0] && !hint_found) + ask = TRUE; + else if (r->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW) { + g_message ("New secrets for %s/%s requested; ask the user", connection_id, r->setting_name); + ask = TRUE; + } else if ( (r->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION) + && is_connection_always_ask (r->connection)) + ask = TRUE; + } + + /* Returned secrets are a{sa{sv}}; this is the outer a{s...} hash that + * will contain all the individual settings hashes. + */ + g_variant_builder_init (&builder_connection, NM_VARIANT_TYPE_CONNECTION); + g_variant_builder_add (&builder_connection, "{sa{sv}}", r->setting_name, &builder_setting); + settings = g_variant_builder_end (&builder_connection); + +done: + g_list_free_full (list, g_object_unref); + if (ask) { + GVariantIter dict_iter; + const char *setting_name; + GVariant *setting_dict; + + /* Stuff all the found secrets into the connection for the UI to use */ + g_variant_iter_init (&dict_iter, settings); + while (g_variant_iter_next (&dict_iter, "{s@a{sv}}", &setting_name, &setting_dict)) { + nm_connection_update_secrets (r->connection, + setting_name, + setting_dict, + NULL); + g_variant_unref (setting_dict); + } + + ask_for_secrets (r); + } else { + /* Otherwise send the secrets back to NetworkManager */ + r->get_callback (NM_SECRET_AGENT_OLD (r->agent), r->connection, error ? NULL : settings, error, r->callback_data); + request_free (r); + } + + if (settings) + g_variant_unref (settings); + g_clear_error (&error); +} + +static void +get_secrets (NMSecretAgentOld *agent, + NMConnection *connection, + const char *connection_path, + const char *setting_name, + const char **hints, + guint32 flags, + NMSecretAgentOldGetSecretsFunc callback, + gpointer callback_data) +{ + AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (agent); + Request *r; + GError *error = NULL; + NMSettingConnection *s_con; + NMSetting *setting; + const char *uuid, *ctype; + GHashTable *attrs; + + setting = nm_connection_get_setting_by_name (connection, setting_name); + if (!setting) { + error = g_error_new (NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, + "%s.%d - Connection didn't have requested setting '%s'.", + __FILE__, __LINE__, setting_name); + callback (agent, connection, NULL, error, callback_data); + g_error_free (error); + return; + } + + uuid = nm_connection_get_uuid (connection); + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + ctype = nm_setting_connection_get_connection_type (s_con); + + if (!uuid || !ctype) { + error = g_error_new (NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, + "%s.%d - Connection didn't have required UUID.", + __FILE__, __LINE__); + callback (agent, connection, NULL, error, callback_data); + g_error_free (error); + return; + } + + /* Track the secrets request */ + r = request_new (agent, connection, connection_path, setting_name, hints, flags, callback, NULL, NULL, callback_data); + g_hash_table_insert (priv->requests, GUINT_TO_POINTER (r->id), r); + + /* VPN passwords are handled by the VPN plugin's auth dialog */ + if (!strcmp (ctype, NM_SETTING_VPN_SETTING_NAME)) { + ask_for_secrets (r); + return; + } + + /* Only handle non-VPN secrets if we're supposed to */ + if (priv->vpn_only == TRUE) { + error = g_error_new_literal (NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_NO_SECRETS, + "Only handling VPN secrets at this time."); + callback (agent, connection, NULL, error, callback_data); + g_error_free (error); + return; + } + + /* For everything else we scrape the keyring for secrets first, and ask + * later if required. + */ + attrs = secret_attributes_build (&network_manager_secret_schema, + KEYRING_UUID_TAG, uuid, + KEYRING_SN_TAG, setting_name, + NULL); + + secret_service_search (NULL, &network_manager_secret_schema, attrs, + SECRET_SEARCH_ALL | SECRET_SEARCH_UNLOCK | SECRET_SEARCH_LOAD_SECRETS, + r->cancellable, keyring_find_secrets_cb, r); + + r->keyring_calls++; + g_hash_table_unref (attrs); +} + +/*******************************************************/ + +static void +cancel_get_secrets (NMSecretAgentOld *agent, + const char *connection_path, + const char *setting_name) +{ + AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (agent); + GHashTableIter iter; + Request *r; + GError *error; + + error = g_error_new_literal (NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_AGENT_CANCELED, + "Canceled by NetworkManager"); + + g_hash_table_iter_init (&iter, priv->requests); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &r)) { + /* Only care about GetSecrets requests here */ + if (r->get_callback == NULL) + continue; + + /* Cancel any matching GetSecrets call */ + if ( g_strcmp0 (r->path, connection_path) == 0 + && g_strcmp0 (r->setting_name, setting_name) == 0) { + /* cancel outstanding keyring operations */ + g_cancellable_cancel (r->cancellable); + + r->get_callback (NM_SECRET_AGENT_OLD (r->agent), r->connection, NULL, error, r->callback_data); + g_hash_table_iter_remove (&iter); + g_signal_emit (r->agent, signals[CANCEL_SECRETS], 0, GUINT_TO_POINTER (r->id)); + } + } + + g_error_free (error); +} + +/*******************************************************/ + +static void +save_request_try_complete (Request *r) +{ + /* Only call the SaveSecrets callback and free the request when all the + * secrets have been saved to the keyring. + */ + if (r->keyring_calls == 0) { + if (!g_cancellable_is_cancelled (r->cancellable)) + r->save_callback (NM_SECRET_AGENT_OLD (r->agent), r->connection, NULL, r->callback_data); + request_free (r); + } +} + +static void +save_secret_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + secret_password_store_finish (result, NULL); + save_request_try_complete (user_data); +} + + + +static GHashTable * +_create_keyring_add_attr_list (NMConnection *connection, + const char *setting_name, + const char *setting_key, + char **out_display_name) +{ + const char *connection_id, *connection_uuid; + + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (setting_name != NULL, NULL); + g_return_val_if_fail (setting_key != NULL, NULL); + + connection_uuid = nm_connection_get_uuid (connection); + g_assert (connection_uuid); + connection_id = nm_connection_get_id (connection); + g_assert (connection_id); + + if (out_display_name) { + *out_display_name = g_strdup_printf ("Network secret for %s/%s/%s", + connection_id, + setting_name, + setting_key); + } + + return secret_attributes_build (&network_manager_secret_schema, + KEYRING_UUID_TAG, connection_uuid, + KEYRING_SN_TAG, setting_name, + KEYRING_SK_TAG, setting_key, + NULL); +} + +static void +save_one_secret (Request *r, + NMSetting *setting, + const char *key, + const char *secret, + const char *display_name) +{ + GHashTable *attrs; + char *alt_display_name = NULL; + const char *setting_name; + NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; + + /* Don't system-owned or always-ask secrets */ + if (!nm_setting_get_secret_flags (setting, key, &secret_flags, NULL)) + return; + if (secret_flags != NM_SETTING_SECRET_FLAG_AGENT_OWNED) + return; + + setting_name = nm_setting_get_name (setting); + g_assert (setting_name); + + attrs = _create_keyring_add_attr_list (r->connection, + setting_name, + key, + display_name ? NULL : &alt_display_name); + g_assert (attrs); + + secret_password_storev (&network_manager_secret_schema, attrs, NULL, + display_name ? display_name : alt_display_name, secret, + r->cancellable, save_secret_cb, r); + r->keyring_calls++; + + g_hash_table_unref (attrs); + g_free (alt_display_name); +} + +static void +vpn_secret_iter_cb (const char *key, const char *secret, gpointer user_data) +{ + Request *r = user_data; + NMSetting *setting; + const char *service_name, *id; + char *display_name; + + if (secret && strlen (secret)) { + setting = nm_connection_get_setting (r->connection, NM_TYPE_SETTING_VPN); + g_assert (setting); + service_name = nm_setting_vpn_get_service_type (NM_SETTING_VPN (setting)); + g_assert (service_name); + id = nm_connection_get_id (r->connection); + g_assert (id); + + display_name = g_strdup_printf ("VPN %s secret for %s/%s/" NM_SETTING_VPN_SETTING_NAME, + key, + id, + service_name); + save_one_secret (r, setting, key, secret, display_name); + g_free (display_name); + } +} + +static void +write_one_secret_to_keyring (NMSetting *setting, + const char *key, + const GValue *value, + GParamFlags flags, + gpointer user_data) +{ + Request *r = user_data; + GType type = G_VALUE_TYPE (value); + const char *secret; + + /* Non-secrets obviously don't get saved in the keyring */ + if (!(flags & NM_SETTING_PARAM_SECRET)) + return; + + if (NM_IS_SETTING_VPN (setting) && (g_strcmp0 (key, NM_SETTING_VPN_SECRETS) == 0)) { + g_return_if_fail (type == G_TYPE_HASH_TABLE); + + /* Process VPN secrets specially since it's a hash of secrets, not just one */ + nm_setting_vpn_foreach_secret (NM_SETTING_VPN (setting), vpn_secret_iter_cb, r); + } else { + /* FIXME: password-raw is not string */ + if (!g_strcmp0 (key, NM_SETTING_802_1X_PASSWORD_RAW)) + return; + g_return_if_fail (type == G_TYPE_STRING); + secret = g_value_get_string (value); + if (secret && strlen (secret)) + save_one_secret (r, setting, key, secret, NULL); + } +} + +static void +save_delete_cb (NMSecretAgentOld *agent, + NMConnection *connection, + GError *error, + gpointer user_data) +{ + Request *r = user_data; + + /* Ignore errors; now save all new secrets */ + nm_connection_for_each_setting_value (connection, write_one_secret_to_keyring, r); + + /* If no secrets actually got saved there may be nothing to do so + * try to complete the request here. If there were secrets to save the + * request will get completed when those keyring calls return. + */ + save_request_try_complete (r); +} + +static void +save_secrets (NMSecretAgentOld *agent, + NMConnection *connection, + const char *connection_path, + NMSecretAgentOldSaveSecretsFunc callback, + gpointer callback_data) +{ + AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (agent); + Request *r; + + r = request_new (agent, connection, connection_path, NULL, NULL, FALSE, NULL, callback, NULL, callback_data); + g_hash_table_insert (priv->requests, GUINT_TO_POINTER (r->id), r); + + g_message("save secret ........................"); + /* First delete any existing items in the keyring */ + nm_secret_agent_old_delete_secrets (agent, connection, save_delete_cb, r); +} + +/*******************************************************/ + +static void +delete_find_items_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + Request *r = user_data; + GError *secret_error = NULL; + GError *error = NULL; + + r->keyring_calls--; + if (g_cancellable_is_cancelled (r->cancellable)) { + /* Callback already called by NM or dispose */ + request_free (r); + return; + } + + secret_password_clear_finish (result, &secret_error); + if (secret_error != NULL) { + error = g_error_new (NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + "The request could not be completed (%s)", + secret_error->message); + g_error_free (secret_error); + } + + r->delete_callback (r->agent, r->connection, error, r->callback_data); + request_free (r); +} + +static void +delete_secrets (NMSecretAgentOld *agent, + NMConnection *connection, + const char *connection_path, + NMSecretAgentOldDeleteSecretsFunc callback, + gpointer callback_data) +{ + AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (agent); + Request *r; + NMSettingConnection *s_con; + const char *uuid; + + r = request_new (agent, connection, connection_path, NULL, NULL, FALSE, NULL, NULL, callback, callback_data); + g_hash_table_insert (priv->requests, GUINT_TO_POINTER (r->id), r); + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + uuid = nm_setting_connection_get_uuid (s_con); + g_assert (uuid); + + secret_password_clear (&network_manager_secret_schema, r->cancellable, + delete_find_items_cb, r, + KEYRING_UUID_TAG, uuid, + NULL); + r->keyring_calls++; +} + +void +applet_agent_handle_vpn_only (AppletAgent *agent, gboolean vpn_only) +{ + g_return_if_fail (agent != NULL); + g_return_if_fail (APPLET_IS_AGENT (agent)); + + APPLET_AGENT_GET_PRIVATE (agent)->vpn_only = vpn_only; +} + +/*******************************************************/ + +AppletAgent * +applet_agent_new (GError **error) +{ + AppletAgent *agent; + + agent = g_object_new (APPLET_TYPE_AGENT, + NM_SECRET_AGENT_OLD_IDENTIFIER, "org.freedesktop.nm-applet", + NM_SECRET_AGENT_OLD_CAPABILITIES, NM_SECRET_AGENT_CAPABILITY_VPN_HINTS, + NULL); + if (!g_initable_init (G_INITABLE (agent), NULL, error)) { + g_object_unref (agent); + return NULL; + } + + return agent; +} + +static void +applet_agent_init (AppletAgent *self) +{ + AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (self); + + priv->requests = g_hash_table_new (g_direct_hash, g_direct_equal); +} + +static void +dispose (GObject *object) +{ + AppletAgent *self = APPLET_AGENT (object); + AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (self); + + if (!priv->disposed) { + GHashTableIter iter; + Request *r; + + /* Mark any outstanding requests as canceled */ + g_hash_table_iter_init (&iter, priv->requests); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &r)) + g_cancellable_cancel (r->cancellable); + + g_hash_table_destroy (priv->requests); + priv->disposed = TRUE; + } + + G_OBJECT_CLASS (applet_agent_parent_class)->dispose (object); +} + +static void applet_agent_class_init (AppletAgentClass *agent_class) +{ + g_message("applet_agent_class_init........................"); + GObjectClass *object_class = G_OBJECT_CLASS (agent_class); + NMSecretAgentOldClass *parent_class = NM_SECRET_AGENT_OLD_CLASS (agent_class); + + g_type_class_add_private (agent_class, sizeof (AppletAgentPrivate)); + + /* virtual methods */ + object_class->dispose = dispose; + parent_class->get_secrets = get_secrets; + parent_class->cancel_get_secrets = cancel_get_secrets; + parent_class->save_secrets = save_secrets; + parent_class->delete_secrets = delete_secrets; + + /* Signals */ + signals[GET_SECRETS] = + g_signal_new (APPLET_AGENT_GET_SECRETS, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (AppletAgentClass, get_secrets), + NULL, NULL, NULL, + G_TYPE_NONE, 7, + G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_POINTER, G_TYPE_POINTER); + + signals[CANCEL_SECRETS] = + g_signal_new (APPLET_AGENT_CANCEL_SECRETS, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (AppletAgentClass, cancel_secrets), + NULL, NULL, NULL, + G_TYPE_NONE, 1, G_TYPE_POINTER); +} + diff --git a/src/backend/dbus-interface/kylinagent.h b/src/backend/dbus-interface/kylinagent.h new file mode 100644 index 00000000..82ec3445 --- /dev/null +++ b/src/backend/dbus-interface/kylinagent.h @@ -0,0 +1,60 @@ +#ifndef __KYLINNMANGENT_H__ +#define __KYLINNMANGENT_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include +#include +#include +#include +#include + +#define APPLET_TYPE_AGENT (applet_agent_get_type ()) +#define APPLET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), APPLET_TYPE_AGENT, AppletAgent)) +#define APPLET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), APPLET_TYPE_AGENT, AppletAgentClass)) +#define APPLET_IS_AGENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), APPLET_TYPE_AGENT)) +#define APPLET_IS_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), APPLET_TYPE_AGENT)) +#define APPLET_AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), APPLET_TYPE_AGENT, AppletAgentClass)) + +#define APPLET_AGENT_GET_SECRETS "get-secrets" +#define APPLET_AGENT_CANCEL_SECRETS "cancel-secrets" + +typedef struct { + NMSecretAgentOld parent; +} AppletAgent; + +typedef void (*AppletAgentSecretsCallback) (AppletAgent *self, + GVariant *secrets, + GError *error, + gpointer user_data); + +typedef struct { + NMSecretAgentOldClass parent_class; + + void (*get_secrets) (AppletAgent *self, + void *request_id, + NMConnection *connection, + const char *setting_name, + const char **hints, + guint32 flags, + AppletAgentSecretsCallback callback, + gpointer callback_data); + + void (*cancel_secrets) (AppletAgent *self, + void *request_id); +} AppletAgentClass; + + +GType applet_agent_get_type (void) G_GNUC_CONST; + +AppletAgent *applet_agent_new (GError **error); + +void applet_agent_handle_vpn_only (AppletAgent *agent, gboolean vpn_only); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/backend/dbus-interface/kylinagentinterface.c b/src/backend/dbus-interface/kylinagentinterface.c new file mode 100644 index 00000000..35a7d41a --- /dev/null +++ b/src/backend/dbus-interface/kylinagentinterface.c @@ -0,0 +1,428 @@ +#include "kylinagentinterface.h" +#include "kylinagent.h" +#include "kylinvpnrequest.h" + +#include +#include + +GSList * secrets_reqs; +#if 0 +typedef struct _SecretsRequest SecretsRequest; +typedef void (*SecretsRequestFreeFunc) (SecretsRequest *req); + +struct _SecretsRequest { + size_t totsize; + gpointer reqid; + char *setting_name; + char **hints; + guint32 flags; + AppletAgent *agent; + AppletAgentSecretsCallback callback; + gpointer callback_data; + + NMConnection *connection; + + /* Class-specific stuff */ + SecretsRequestFreeFunc free_func; +}; +#endif +typedef struct { + SecretsRequest req; + GtkWidget *dialog; +} NMWifiInfo; + +static AppletAgent * kylinAgent = NULL; + +void +applet_secrets_request_set_free_func (SecretsRequest *req, + SecretsRequestFreeFunc free_func) +{ + req->free_func = free_func; +} + +static void +show_ignore_focus_stealing_prevention (GtkWidget *widget) +{ + gtk_widget_realize (widget); + gtk_widget_show (widget); + gtk_window_present (GTK_WINDOW (widget)); +} + +static GVariant * +remove_unwanted_secrets (GVariant *secrets, gboolean keep_8021X) +{ + GVariant *copy, *setting_dict; + const char *setting_name; + GVariantBuilder conn_builder; + GVariantIter conn_iter; + + g_variant_builder_init (&conn_builder, NM_VARIANT_TYPE_CONNECTION); + g_variant_iter_init (&conn_iter, secrets); + while (g_variant_iter_next (&conn_iter, "{&s@a{sv}}", &setting_name, &setting_dict)) { + if ( !strcmp (setting_name, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) + || (!strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) && keep_8021X)) + g_variant_builder_add (&conn_builder, "{s@a{sv}}", setting_name, setting_dict); + + g_variant_unref (setting_dict); + } + copy = g_variant_builder_end (&conn_builder); + g_variant_unref (secrets); + + return copy; +} + +static void +free_wifi_info (SecretsRequest *req) +{ + NMWifiInfo *info = (NMWifiInfo *) req; + + if (info->dialog) { + gtk_widget_hide (info->dialog); + gtk_widget_destroy (info->dialog); + info->dialog = NULL; + } +} + + +void +applet_secrets_request_free (SecretsRequest *req) +{ + g_return_if_fail (req != NULL); + + if (req->free_func) + req->free_func (req); + + secrets_reqs = g_slist_remove (secrets_reqs, req); + + g_object_unref (req->connection); + g_free (req->setting_name); + g_strfreev (req->hints); + memset (req, 0, req->totsize); + g_free (req); +} + +void +applet_secrets_request_complete (SecretsRequest *req, + GVariant *settings, + GError *error) +{ + req->callback (req->agent, error ? NULL : settings, error, req->callback_data); +} + +static void +get_secrets_dialog_response_cb (GtkDialog *foo, + gint response, + gpointer user_data) +{ + SecretsRequest *req = user_data; + NMWifiInfo *info = (NMWifiInfo *) req; + NMAWifiDialog *dialog = NMA_WIFI_DIALOG (info->dialog); + NMConnection *connection = NULL; + NMSettingWirelessSecurity *s_wireless_sec; + GVariant *secrets = NULL; + const char *key_mgmt, *auth_alg; + gboolean keep_8021X = FALSE; + GError *error = NULL; + + if (response != GTK_RESPONSE_OK) { + g_set_error (&error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_USER_CANCELED, + "%s.%d (%s): canceled", + __FILE__, __LINE__, __func__); + goto done; + } + + connection = nma_wifi_dialog_get_connection (dialog, NULL, NULL); + if (!connection) { + g_set_error (&error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + "%s.%d (%s): couldn't get connection from Wi-Fi dialog.", + __FILE__, __LINE__, __func__); + goto done; + } + + /* Second-guess which setting NM wants secrets for. */ + s_wireless_sec = nm_connection_get_setting_wireless_security (connection); + if (!s_wireless_sec) { + g_set_error (&error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, + "%s.%d (%s): requested setting '802-11-wireless-security'" + " didn't exist in the connection.", + __FILE__, __LINE__, __func__); + goto done; /* Unencrypted */ + } + + secrets = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + if (!secrets) { + g_set_error (&error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + "%s.%d (%s): failed to hash connection '%s'.", + __FILE__, __LINE__, __func__, nm_connection_get_id (connection)); + goto done; + } + /* If the user chose an 802.1x-based auth method, return 802.1x secrets, + * not wireless secrets. Can happen with Dynamic WEP, because NM doesn't + * know the capabilities of the AP (since Dynamic WEP APs don't broadcast + * beacons), and therefore defaults to requesting WEP secrets from the + * wireless-security setting, not the 802.1x setting. + */ + key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wireless_sec); + if (!strcmp (key_mgmt, "ieee8021x") || !strcmp (key_mgmt, "wpa-eap")) { + /* LEAP secrets aren't in the 802.1x setting */ + auth_alg = nm_setting_wireless_security_get_auth_alg (s_wireless_sec); + if (!auth_alg || strcmp (auth_alg, "leap")) { + NMSetting8021x *s_8021x; + + s_8021x = nm_connection_get_setting_802_1x (connection); + if (!s_8021x) { + g_set_error (&error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, + "%s.%d (%s): requested setting '802-1x' didn't" + " exist in the connection.", + __FILE__, __LINE__, __func__); + goto done; + } + keep_8021X = TRUE; + } + } + + /* Remove all not-relevant secrets (inner dicts) */ + secrets = remove_unwanted_secrets (secrets, keep_8021X); + g_variant_take_ref (secrets); + +done: + applet_secrets_request_complete (req, secrets, error); + applet_secrets_request_free (req); + + if (secrets) + g_variant_unref (secrets); + if (connection) + nm_connection_clear_secrets (connection); +} + +static gboolean +wifi_get_secrets (SecretsRequest *req, GError **error) +{ + NMWifiInfo *info = (NMWifiInfo *) req; + + g_return_val_if_fail (!info->dialog, FALSE); + +#if GTK_CHECK_VERSION(3,90,0) + gtk_init (); +#else + int argc = 0; + char ***argv = NULL; + gtk_init (&argc, &argv); +#endif + + NMClient *nm_client = nm_client_new (NULL, NULL); + if (!nm_client) { + g_set_error (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + "%s.%d (%s): create nm client failed.", + __FILE__, __LINE__, __func__); + g_warning ("create nm client failed"); + goto l_out; + } + + + info->dialog = nma_wifi_dialog_new_for_secrets (nm_client, + req->connection, + req->setting_name, + (const char *const*) req->hints); + + if (info->dialog) { + applet_secrets_request_set_free_func (req, free_wifi_info); + g_signal_connect (info->dialog, "response", + G_CALLBACK (get_secrets_dialog_response_cb), + info); + show_ignore_focus_stealing_prevention (info->dialog); + } else { + g_set_error (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + "%s.%d (%s): couldn't display secrets UI", + __FILE__, __LINE__, __func__); + } + + g_clear_object(&nm_client); + +l_out: + return !!info->dialog; + //return 0; +} + +static SecretsRequest * +applet_secrets_request_new (size_t totsize, + NMConnection *connection, + gpointer request_id, + const char *setting_name, + const char **hints, + guint32 flags, + AppletAgentSecretsCallback callback, + gpointer callback_data, + AppletAgent *agent) +{ + SecretsRequest *req; + + g_return_val_if_fail (totsize >= sizeof (SecretsRequest), NULL); + g_return_val_if_fail (connection != NULL, NULL); + + req = g_malloc0 (totsize); + req->totsize = totsize; + req->connection = g_object_ref (connection); + req->reqid = request_id; + req->setting_name = g_strdup (setting_name); + req->hints = g_strdupv ((char **) hints); + req->flags = flags; + req->callback = callback; + req->callback_data = callback_data; + req->agent = agent; + return req; +} + +static void +get_existing_secrets_cb (NMSecretAgentOld *agent, + NMConnection *connection, + GVariant *secrets, + GError *secrets_error, + gpointer user_data) +{ + SecretsRequest *req = user_data; + //NMADeviceClass *dclass; + GError *error = NULL; + + if (secrets) + nm_connection_update_secrets (connection, req->setting_name, secrets, NULL); + else + nm_connection_clear_secrets (connection); + + /* Let the device class handle secrets */ + if (!wifi_get_secrets(req, &error)) { + g_warning ("%s:%d - %s", __func__, __LINE__, error ? error->message : "(unknown)"); + applet_secrets_request_complete (req, NULL, error); + applet_secrets_request_free (req); + g_error_free (error); + } + /* Otherwise success; wait for the secrets callback */ +} + + +static void +applet_agent_get_secrets_cb (AppletAgent *agent, + gpointer request_id, + NMConnection *connection, + const char *setting_name, + const char **hints, + guint32 flags, + AppletAgentSecretsCallback callback, + gpointer callback_data, + gpointer user_data) +{ + NMSettingConnection *s_con; + GError *error = NULL; + SecretsRequest *req = NULL; + + s_con = nm_connection_get_setting_connection (connection); + g_return_if_fail (s_con != NULL); + + /* VPN secrets get handled a bit differently */ + if (!strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_VPN_SETTING_NAME)) { + req = applet_secrets_request_new (applet_vpn_request_get_secrets_size (), + connection, + request_id, + setting_name, + hints, + flags, + callback, + callback_data, + agent); + if (!applet_vpn_request_get_secrets (req, &error)) + goto error; + + secrets_reqs = g_slist_prepend (secrets_reqs, req); + return; + } + + + req = applet_secrets_request_new (sizeof (NMWifiInfo), + connection, + request_id, + setting_name, + hints, + flags, + callback, + callback_data, + agent); + secrets_reqs = g_slist_prepend (secrets_reqs, req); + + /* Get existing secrets, if any */ + nm_secret_agent_old_get_secrets (NM_SECRET_AGENT_OLD (agent), + connection, + setting_name, + hints, + NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE, + get_existing_secrets_cb, + req); + return; + +error: + g_warning ("%s", error->message); + callback (agent, NULL, error, callback_data); + g_error_free (error); + + if (req) + applet_secrets_request_free (req); +} + +static void +applet_agent_cancel_secrets_cb (AppletAgent *agent, + gpointer request_id, + gpointer user_data) +{ + GSList *iter, *next; + + for (iter = secrets_reqs; iter; iter = next) { + SecretsRequest *req = iter->data; + + next = g_slist_next (iter); + + if (req->reqid == request_id) { + /* cancel and free this password request */ + applet_secrets_request_free (req); + break; + } + } +} + +void agent_init() +{ + if (NULL != kylinAgent) { + return; + } + GError *error = NULL; + kylinAgent = applet_agent_new (&error); + + g_signal_connect (kylinAgent, APPLET_AGENT_GET_SECRETS, + G_CALLBACK (applet_agent_get_secrets_cb), NULL); + g_signal_connect (kylinAgent, APPLET_AGENT_CANCEL_SECRETS, + G_CALLBACK (applet_agent_cancel_secrets_cb), NULL); + + + return; +} + +void agent_clear() +{ + if (NULL == kylinAgent) { + return; + } + g_clear_object (&kylinAgent); + kylinAgent = NULL; +} diff --git a/src/backend/dbus-interface/kylinagentinterface.h b/src/backend/dbus-interface/kylinagentinterface.h new file mode 100644 index 00000000..2a097923 --- /dev/null +++ b/src/backend/dbus-interface/kylinagentinterface.h @@ -0,0 +1,10 @@ +#ifndef __KYLINAGENTINTERFACE_H__ +#define __KYLINAGENTINTERFACE_H__ +#ifdef __cplusplus +extern "C"{ +void agent_init(); +void agent_clear(); +} +#endif + +#endif // NMAGENT_H diff --git a/src/backend/dbus-interface/kylinapconnectitem.cpp b/src/backend/dbus-interface/kylinapconnectitem.cpp new file mode 100644 index 00000000..1f8945d7 --- /dev/null +++ b/src/backend/dbus-interface/kylinapconnectitem.cpp @@ -0,0 +1,19 @@ + +#include "kylinapconnectitem.h" + +KyApConnectItem::KyApConnectItem(QObject *parent) : QObject(parent) +{ + m_connectName = ""; + m_connectUuid = ""; + m_connectSsid = ""; + m_ifaceName = ""; + m_password = ""; + m_band = ""; + m_isActivated = false; +} + + +KyApConnectItem::~KyApConnectItem() +{ + +} diff --git a/src/backend/dbus-interface/kylinapconnectitem.h b/src/backend/dbus-interface/kylinapconnectitem.h new file mode 100644 index 00000000..f7a1e27d --- /dev/null +++ b/src/backend/dbus-interface/kylinapconnectitem.h @@ -0,0 +1,25 @@ +#ifndef KYLINAPCONNECTITEM_H +#define KYLINAPCONNECTITEM_H + +#include + +class KyApConnectItem : public QObject +{ + Q_OBJECT + +public: + explicit KyApConnectItem(QObject *parent = nullptr); + ~KyApConnectItem(); + +public: + QString m_connectName; + QString m_connectSsid; + QString m_connectUuid; + QString m_ifaceName; + QString m_password; + QString m_band; + bool m_isActivated; + +}; + +#endif // KYLINAPCONNECTITEM_H diff --git a/src/backend/dbus-interface/kylinbluetoothconnectitem.cpp b/src/backend/dbus-interface/kylinbluetoothconnectitem.cpp new file mode 100644 index 00000000..1fc2897b --- /dev/null +++ b/src/backend/dbus-interface/kylinbluetoothconnectitem.cpp @@ -0,0 +1,29 @@ +#include "kylinbluetoothconnectitem.h" + + +KyBluetoothConnectItem::KyBluetoothConnectItem(QObject *parent) : QObject(parent) +{ + m_connectName = ""; + m_connectUuid = ""; + + m_deviceAddress = ""; + + m_ipv4Address = ""; + m_ipv6Address = ""; + + m_state = NetworkManager::ActiveConnection::State::Deactivated; +} + +KyBluetoothConnectItem::~KyBluetoothConnectItem() +{ + m_connectName = ""; + m_connectUuid = ""; + + m_deviceAddress = ""; + + m_ipv4Address = ""; + m_ipv6Address = ""; + + m_state = NetworkManager::ActiveConnection::State::Deactivated; +} + diff --git a/src/backend/dbus-interface/kylinbluetoothconnectitem.h b/src/backend/dbus-interface/kylinbluetoothconnectitem.h new file mode 100644 index 00000000..3bedeb21 --- /dev/null +++ b/src/backend/dbus-interface/kylinbluetoothconnectitem.h @@ -0,0 +1,33 @@ +#ifndef KYLINBLUETOOTHCONNECTITEM_H +#define KYLINBLUETOOTHCONNECTITEM_H + +#include +#include +#include +#include + +class KyBluetoothConnectItem : public QObject +{ + Q_OBJECT +public: + explicit KyBluetoothConnectItem(QObject *parent = nullptr); + ~KyBluetoothConnectItem(); + +public: + void dumpInfo(); + +public: + QString m_connectName; + QString m_connectUuid; + + QString m_deviceAddress; + + QString m_ipv4Address; + QString m_ipv6Address; + + NetworkManager::ActiveConnection::State m_state; //deactive、activing and actived + //QString m_itemType; //activeconnect or connect + +}; + +#endif // KYLINBLUETOOTHCONNECTITEM_H diff --git a/src/backend/dbus-interface/kylinconnectitem.cpp b/src/backend/dbus-interface/kylinconnectitem.cpp new file mode 100644 index 00000000..011dee63 --- /dev/null +++ b/src/backend/dbus-interface/kylinconnectitem.cpp @@ -0,0 +1,35 @@ + +#include "kylinconnectitem.h" + +KyConnectItem::KyConnectItem(QObject *parent) : QObject(parent) +{ + m_connectName = ""; + m_connectUuid = ""; + m_connectPath = ""; + + m_ifaceName = ""; + + m_connectState = NetworkManager::ActiveConnection::State::Unknown; //deactive、activing and actived + m_itemType = NetworkManager::ConnectionSettings::ConnectionType::Unknown; +} + +KyConnectItem::~KyConnectItem() +{ + +} + +void KyConnectItem::setConnectUuid(QString uuid) +{ + m_connectUuid = uuid; +} + +void KyConnectItem::dumpInfo() +{ + qDebug()<<"wired connection item info:"; + qDebug()<<"connect name:"< +#include "kylinnetworkresourcemanager.h" + +class KyConnectItem : public QObject +{ + Q_OBJECT +public: + explicit KyConnectItem(QObject *parent = nullptr); + ~KyConnectItem(); + +public: + void dumpInfo(); + + void setConnectUuid(QString uuid); + +public: + QString m_connectName; + QString m_connectUuid; + QString m_connectPath; + + QString m_ifaceName; + + NetworkManager::ActiveConnection::State m_connectState; //deactive、activing and actived + + NetworkManager::ConnectionSettings::ConnectionType m_itemType; //wired or wireless vpn etc +}; + +#endif // KYLINWIREDCONNECTITEM_H diff --git a/src/backend/dbus-interface/kylinconnectoperation.cpp b/src/backend/dbus-interface/kylinconnectoperation.cpp new file mode 100644 index 00000000..daf8234f --- /dev/null +++ b/src/backend/dbus-interface/kylinconnectoperation.cpp @@ -0,0 +1,248 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * 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, 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 +#include +#include +#include +#include + +KyConnectOperation::KyConnectOperation(QObject *parent) : QObject(parent) +{ + m_networkResourceInstance = KyNetworkResourceManager::getInstance(); +} + +KyConnectOperation::~KyConnectOperation() +{ + m_networkResourceInstance = nullptr; +} + +void KyConnectOperation::ipv4SettingSet( + NetworkManager::Ipv4Setting::Ptr &ipv4Setting, + const KyConnectSetting &connectSettingsInfo) +{ + ipv4Setting->setInitialized(true); + ipv4Setting->setDns(connectSettingsInfo.m_ipv4Dns); + + if (CONFIG_IP_DHCP == connectSettingsInfo.m_ipv4ConfigIpType) { + ipv4Setting->setMethod(NetworkManager::Ipv4Setting::Automatic); + return; + } else { + ipv4Setting->setMethod(NetworkManager::Ipv4Setting::Manual); + } + ipv4Setting->setAddresses(connectSettingsInfo.m_ipv4Address); + + return; +} +void KyConnectOperation::ipv6SettingSet( + NetworkManager::Ipv6Setting::Ptr &ipv6Setting, + const KyConnectSetting &connectSettingsInfo) +{ + ipv6Setting->setInitialized(true); + ipv6Setting->setDns(connectSettingsInfo.m_ipv6Dns); + + if (CONFIG_IP_DHCP == connectSettingsInfo.m_ipv6ConfigIpType) { + ipv6Setting->setMethod(NetworkManager::Ipv6Setting::Automatic); + ipv6Setting->setPrivacy(NetworkManager::Ipv6Setting::Disabled); + return; + } + + ipv6Setting->setMethod(NetworkManager::Ipv6Setting::Manual); + ipv6Setting->setAddresses(connectSettingsInfo.m_ipv6Address); + + return ; +} + +void KyConnectOperation::connectSettingSet( + NetworkManager::ConnectionSettings::Ptr connectionSettings, + const KyConnectSetting &connectSettingsInfo) +{ + connectionSettings->setId(connectSettingsInfo.m_connectName); + connectionSettings->setUuid(NetworkManager::ConnectionSettings::createNewUuid()); + connectionSettings->setAutoconnect(true); + connectionSettings->setAutoconnectPriority(0); + if (!connectSettingsInfo.m_ifaceName.isEmpty()) { + connectionSettings->setInterfaceName(connectSettingsInfo.m_ifaceName); + } + return; +} + +void KyConnectOperation::setAutoConnect(NetworkManager::ConnectionSettings::Ptr &connectSetting, + bool bAutoConnect) +{ + if (connectSetting.isNull()) { + return; + } + + connectSetting->setAutoconnect(bAutoConnect); + + return; +} + +void KyConnectOperation::createConnect(KyConnectSetting &connectSettingsInfo) +{ + qDebug()<<"create connect need to do"; + return; +} + +void KyConnectOperation::updateConnect(NetworkManager::ConnectionSettings::Ptr connectionSettings, const KyConnectSetting &connectSettingsInfo) +{ + qDebug()<<"update connect"<uuid(); + + NetworkManager::Ipv4Setting::Ptr ipv4Setting = connectionSettings->setting(NetworkManager::Setting::Ipv4).dynamicCast(); + ipv4SettingSet(ipv4Setting, connectSettingsInfo); + + NetworkManager::Ipv6Setting::Ptr ipv6Setting = connectionSettings->setting(NetworkManager::Setting::Ipv6).dynamicCast(); + ipv6SettingSet(ipv6Setting, connectSettingsInfo); + +// NetworkManager::WiredSetting::Ptr wiredSetting = connectionSettings->setting(NetworkManager::Setting::Wired).dynamicCast(); +// wiredSetting->setInitialized(true); + + return ; +} + +void KyConnectOperation::deleteConnect(const QString &connectUuid) +{ + qDebug()<<"delete connect uuid " << connectUuid; + + NetworkManager::Connection::Ptr connectPtr = + NetworkManager::findConnectionByUuid(connectUuid); + if (nullptr == connectPtr) { + QString errorMessage = tr("it can not find connection") + connectUuid; + qWarning()<remove(); + + return ; +} + +void KyConnectOperation::activateConnection(const QString connectUuid, const QString deviceName) +{ + QString connectPath = ""; + QString deviceIdentifier = ""; + QString connectName = ""; + QString specificObject = ""; + NetworkManager::Connection::Ptr connectPtr = nullptr; + + qDebug()<<"it will activate connect"<settings()->connectionType()) { + QString errorMessage = tr("the connect type is") + + connectPtr->settings()->connectionType() + + tr(", but it is not wired"); + qWarning()<path(); + connectName = connectPtr->name(); +// deviceName = connectPtr->settings()->interfaceName(); + +// for (auto const & dev : m_networkResourceInstance->m_devices) { +// for (auto const & dev_conn : dev->availableConnections()) { +// if (dev_conn == connectPtr) { +// deviceIdentifier = dev->uni(); +// deviceName = dev->interfaceName(); +// break; +// } +// } +// } + + auto dev = m_networkResourceInstance->findDeviceInterface(deviceName); + if (!dev.isNull()) { + deviceIdentifier = dev->uni(); + } + + + if (deviceIdentifier.isEmpty()) { + QString errorMessage = tr("device Identifier is empty, its name") + deviceName; + qWarning() << errorMessage; + Q_EMIT activateConnectionError(errorMessage); + return ; + } + + qDebug() <<"active wired connect: path "<< connectPath + << "device identify " << deviceIdentifier + << "connect name " << connectName + << "device name" << deviceName + << "specific parameter"<< specificObject; + + QDBusPendingCallWatcher * watcher; + watcher = new QDBusPendingCallWatcher{NetworkManager::activateConnection(connectPath, deviceIdentifier, specificObject), this}; + connect(watcher, &QDBusPendingCallWatcher::finished, [this, connectName, deviceName] (QDBusPendingCallWatcher * watcher) { + if (watcher->isError() || !watcher->isValid()) { + QString errorMessage = tr("activate connection failed: ") + watcher->error().message(); + qWarning()<activateConnectionError(errorMessage); + } else { + qWarning()<<"active wired connect complete."; + } + + watcher->deleteLater(); + }); + + return ; +} + +void KyConnectOperation::deactivateConnection(const QString activeConnectName, const QString &activeConnectUuid) +{ + NetworkManager::ActiveConnection::Ptr activateConnectPtr = nullptr; + + qDebug()<<"deactivetate connect name"<getActiveConnect(activeConnectUuid); + if (nullptr == activateConnectPtr) { + QString errorMessage = tr("it can not find the activate connect") + + activeConnectName + tr("uuid") + activeConnectUuid; + qWarning()<path(); + QDBusPendingReply<> reply = NetworkManager::deactivateConnection(activateConnectPtr->path()); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); + connect(watcher, &QDBusPendingCallWatcher::finished, [this, activateConnectPtr] (QDBusPendingCallWatcher * watcher) { + if (watcher->isError() || !watcher->isValid()) { + QString errorMessage = tr("deactivation of connection") + + activateConnectPtr->connection()->name() + tr("failed:") + + watcher->error().message(); + + qWarning()<deactivateConnectionError(errorMessage); + } else { + qWarning() << "deactive connect operation finished" << activateConnectPtr->connection()->name(); + } + watcher->deleteLater(); + }); + + return; +} diff --git a/src/backend/dbus-interface/kylinconnectoperation.h b/src/backend/dbus-interface/kylinconnectoperation.h new file mode 100644 index 00000000..fc735d7e --- /dev/null +++ b/src/backend/dbus-interface/kylinconnectoperation.h @@ -0,0 +1,44 @@ +#ifndef KYLINCONNECTOPERATION_H +#define KYLINCONNECTOPERATION_H + +#include "kylinnetworkresourcemanager.h" +#include "kylinconnectsetting.h" + +class KyConnectOperation : public QObject +{ + Q_OBJECT +public: + explicit KyConnectOperation(QObject *parent = nullptr); + ~KyConnectOperation(); + +public: + void createConnect(KyConnectSetting &connectSettingsInfo); + void updateConnect(NetworkManager::ConnectionSettings::Ptr connectionSettings, const KyConnectSetting &connectSettingsInfo); + void deleteConnect(const QString &connectUuid); + void activateConnection(const QString connectUuid, const QString deviceName); + void deactivateConnection(const QString activeConnectName, const QString &activeConnectUuid); + +public: + void connectSettingSet( + NetworkManager::ConnectionSettings::Ptr connectionSettings, + const KyConnectSetting &connectSettingsInfo); + void ipv4SettingSet(NetworkManager::Ipv4Setting::Ptr &ipv4Setting, + const KyConnectSetting &connectSettingsInfo); + void ipv6SettingSet(NetworkManager::Ipv6Setting::Ptr &ipv6Setting, + const KyConnectSetting &connectSettingsInfo); + void setAutoConnect(NetworkManager::ConnectionSettings::Ptr &connectSetting, + bool bAutoConnect); + inline void errorProcess(QString errorMessage); + +signals: + void createConnectionError(QString errorMessage); + void updateConnectionError(QString errorMessage); + void deleteConnectionError(QString errorMessage); + void activateConnectionError(QString errorMessage); + void deactivateConnectionError(QString errorMessage); + +protected: + KyNetworkResourceManager *m_networkResourceInstance = nullptr; +}; + +#endif // KYLINCONNECTOPERATION_H diff --git a/src/backend/dbus-interface/kylinconnectresource.cpp b/src/backend/dbus-interface/kylinconnectresource.cpp new file mode 100644 index 00000000..00d0570a --- /dev/null +++ b/src/backend/dbus-interface/kylinconnectresource.cpp @@ -0,0 +1,777 @@ + +#include "kylinconnectresource.h" +#include "kywirelessconnectoperation.h" +#include "kylinutil.h" + +#include +#include +#include +#include +#include + +const QString str2GBand = "2.4Ghz"; +const QString str5GBand = "5Ghz"; + +static bool subLanListSort(const KyConnectItem* info1, const KyConnectItem* info2) +{ + QString name1 = info1->m_connectName; + QString name2 = info2->m_connectName; + bool result = true; + if (QString::compare(name1, name2, Qt::CaseInsensitive) > 0) { + result = false; + } + return result; +} + +static void lanListSort(QList &list) +{ + qSort(list.begin(), list.end(), subLanListSort); +} + +KyConnectResourse::KyConnectResourse(QObject *parent) : QObject(parent) +{ + m_networkResourceInstance = KyNetworkResourceManager::getInstance(); + + connect(m_networkResourceInstance, &KyNetworkResourceManager::connectionAdd, this, &KyConnectResourse::connectionAdd); + connect(m_networkResourceInstance, &KyNetworkResourceManager::connectionRemove, this, &KyConnectResourse::connectionRemove); + connect(m_networkResourceInstance, &KyNetworkResourceManager::connectionUpdate, this, &KyConnectResourse::connectionUpdate); + connect(m_networkResourceInstance, &KyNetworkResourceManager::connectivityChanged, this, &KyConnectResourse::connectivityChanged); +} + +KyConnectResourse::~KyConnectResourse() +{ + m_networkResourceInstance = nullptr; +} + +KyConnectItem *KyConnectResourse::getConnectionItem(NetworkManager::Connection::Ptr connectPtr, QString devName) +{ + if (nullptr == connectPtr) { + qWarning()<<"[KyConnectResourse]"<<"the connect is empty"; + return nullptr; + } + + KyConnectItem *connectionItem = new KyConnectItem(); + connectionItem->m_connectName = connectPtr->name(); + connectionItem->m_connectUuid = connectPtr->uuid(); + connectionItem->m_connectPath = connectPtr->path(); + + NetworkManager::ConnectionSettings::Ptr settingPtr = connectPtr->settings(); + connectionItem->m_ifaceName = settingPtr->interfaceName(); + connectionItem->m_itemType = settingPtr->connectionType(); + + if (m_networkResourceInstance->isActivatingConnection(connectPtr->uuid())) { + if (connectionItem->m_ifaceName == "" && devName != "") { + if (isActiveDevice(connectionItem->m_connectUuid, devName)) { + connectionItem->m_connectState = NetworkManager::ActiveConnection::State::Activating; + } else { + connectionItem->m_connectState = NetworkManager::ActiveConnection::State::Deactivated; + } + } else { + connectionItem->m_connectState = NetworkManager::ActiveConnection::State::Activating; + } + } else { + connectionItem->m_connectState = NetworkManager::ActiveConnection::State::Deactivated; + } + return connectionItem; +} + +bool KyConnectResourse::isActiveDevice(QString conUuid, QString devName) +{ + QString deviceName = ""; + + NetworkManager::ActiveConnection::Ptr activeConnectPtr = + m_networkResourceInstance->getActiveConnect(conUuid); + + if (nullptr == activeConnectPtr) { + qWarning()<< "[KyConnectResourse]" <<"it can not find activating connect "<< conUuid; + return false; + } + + QStringList interfaces = activeConnectPtr->devices(); + if (interfaces.isEmpty()) { + qWarning()<< "[KyConnectResourse]" << "get device of activing connection failed."; + return false; + } + + QString ifaceUni = ""; + for (int index=0; index < interfaces.size(); index++) { + ifaceUni = interfaces.at(index); + NetworkManager::Device:: Ptr devicePtr = + m_networkResourceInstance->findDeviceUni(ifaceUni); + deviceName = devicePtr->interfaceName(); + if (deviceName == devName) { + return true; + } + } + return false; +} + +KyConnectItem * KyConnectResourse::getConnectionItemByUuid(QString connectUuid) +{ + NetworkManager::Connection::Ptr connectPtr = + m_networkResourceInstance->getConnect(connectUuid); + + if (nullptr == connectPtr) { + qWarning()<< "[KyConnectResourse]" <<"get connect failed, connect uuid"<isActiveConnection(connectPtr->uuid())) { + qDebug()<<"[KyConnectResourse]"<name()<<"is active connection"; + return nullptr; + } + + KyConnectItem *connectItem = getConnectionItem(connectPtr, ""); + if (nullptr != connectItem) { + //connectItem->dumpInfo(); + return connectItem; + } + + return nullptr; +} + +KyConnectItem * KyConnectResourse::getConnectionItemByUuid(QString connectUuid, QString deviceName) +{ + NetworkManager::Connection::Ptr connectPtr = + m_networkResourceInstance->getConnect(connectUuid); + + if (nullptr == connectPtr) { + qWarning()<< "[KyConnectResourse]" <<"get connect failed, connect uuid"<settings()->interfaceName(); + if (!connectInterface.isEmpty() + && deviceName != connectInterface) { + qDebug()<<"[KyConnectResourse]" << "connect name:"<< connectPtr->name() + << "connect device name" << connectInterface; + return nullptr; + } + + if (m_networkResourceInstance->isActiveConnection(connectPtr->uuid())) { + qDebug()<<"[KyConnectResourse]"<name()<<"is active connection"; + return nullptr; + } + + KyConnectItem *connectItem = getConnectionItem(connectPtr, deviceName); + if (nullptr != connectItem) { + //connectItem->dumpInfo(); + return connectItem; + } + + return nullptr; +} + +void KyConnectResourse::getConnectionList(QString deviceName, + NetworkManager::ConnectionSettings::ConnectionType connectionType, + QList &connectItemList) +{ + NetworkManager::Connection::List connectList; + + qDebug()<<"[KyConnectResourse]"<<"get connections item, device" + <getConnectList(); + + if (connectList.empty()) { + qWarning()<<"[KyConnectResourse]"<<"get connection failed, the connect list is empty"; + return; + } + + NetworkManager::Connection::Ptr connectPtr = nullptr; + for (int index = 0; index < connectList.size(); index++) { + connectPtr = connectList.at(index); + if (connectPtr.isNull()) { + continue; + } + + if (connectionType != connectPtr->settings()->connectionType()) { + qDebug()<<"[KyConnectResourse]"<<"connect name:" << connectPtr->name() + <<"connect type:"<settings()->connectionType(); + continue; + } + + QString connectInterface = connectPtr->settings()->interfaceName(); + if (!connectInterface.isEmpty() + && deviceName != connectInterface) { + qDebug() << "[KyConnectResourse]" << "connect name:"<< connectPtr->name() + << "connect device name" << connectInterface; + continue; + } + + if (m_networkResourceInstance->isActiveConnection(connectPtr->uuid())) { + qDebug()<<"[KyConnectResourse]"<name()<<"is active connection"; + continue; + } + + KyConnectItem *connectItem = getConnectionItem(connectPtr, deviceName); + if (nullptr != connectItem) { + // connectItem->m_itemType = connectionType; + connectItemList << connectItem; + //connectItem->dumpInfo(); + } + + connectPtr = nullptr; + } + + if (connectItemList.size() > 1) { + lanListSort(connectItemList); + } + return; +} + +#if 0 +void KyConnectResourse::getWiredConnections(QList &wiredConnectItemList) +{ + int index = 0; + NetworkManager::Connection::List connectList; + + qDebug()<<"[KyConnectResourse]"<<"get wired connections"; + + connectList.clear(); + connectList = m_networkResourceInstance->getConnectList(); + + if (connectList.empty()) { + qWarning()<<"[KyConnectResourse]"<<"get wired connection failed, the connect list is empty"; + return; + } + + NetworkManager::Connection::Ptr connectPtr = nullptr; + for (index = 0; index < connectList.size(); index++) { + connectPtr = connectList.at(index); + if (NetworkManager::ConnectionSettings::ConnectionType::Wired + != connectPtr->settings()->connectionType()) { + qDebug()<<"[KyConnectResourse]"<<"connect name:" << connectPtr->name() + <<"connect type:"<settings()->connectionType(); + continue; + } + + if (m_networkResourceInstance->isActiveConnection(connectPtr->uuid())) { + qDebug()<<"[KyConnectResourse]"<name()<<"is active connection"; + continue; + } + + KyWiredConnectItem *connectItem = getWiredConnectItem(connectPtr); + if (nullptr != connectItem) { + wiredConnectItemList << connectItem; + connectItem->dumpInfo(); + } + + connectPtr = nullptr; + } + + return; +} + +KyWiredConnectItem *KyConnectResourse::getWiredConnectItem(NetworkManager::Connection::Ptr connectPtr) +{ + qDebug()<<"[KyConnectResourse]"<<"get connect item"; + + if (nullptr == connectPtr) { + qWarning()<<"[KyConnectResourse]"<<"the connect is empty"; + return nullptr; + } + + KyWiredConnectItem *wiredItem = new KyWiredConnectItem(); + NetworkManager::ConnectionSettings::Ptr settingPtr = connectPtr->settings(); + + wiredItem->m_connectName = connectPtr->name(); + wiredItem->m_connectUuid = connectPtr->uuid(); + wiredItem->m_ifaceName = settingPtr->interfaceName(); + + getConnectIp(settingPtr, wiredItem->m_ipv4, wiredItem->m_ipv6); + + m_networkdevice->getWiredHardwareInfo(settingPtr->interfaceName(), wiredItem); + + wiredItem->m_state = NetworkManager::ActiveConnection::State::Deactivated; + //wiredItem->m_itemType; + + return wiredItem; +} + +#endif + +void KyConnectResourse::getConnectIp( + NetworkManager::ConnectionSettings::Ptr settingPtr, + QString &ipv4Address, + QString &ipv6Address) +{ + NetworkManager::Ipv4Setting::Ptr ipv4Setting = + settingPtr->setting(NetworkManager::Setting::Ipv4).dynamicCast(); + if (NetworkManager::Ipv4Setting::Manual == ipv4Setting->method()) { + QList ipv4AddressList = ipv4Setting->addresses(); + NetworkManager::IpAddress settingIpv4Address = ipv4AddressList.at(0); + if (settingIpv4Address.isValid()) { + ipv4Address = settingIpv4Address.ip().toString(); + } else { + qWarning()<<"[KyConnectResourse]"<<"get connect ipv4 failed, ipv4Address is not valid"; + } + } else { + qWarning()<<"[KyConnectResourse]"<<"get connect ipv4 failed, ipv4 config with dhcp"; + } + + NetworkManager::Ipv6Setting::Ptr ipv6Setting = settingPtr->setting(NetworkManager::Setting::Ipv6).dynamicCast(); + if (nullptr !=ipv6Setting + && NetworkManager::Ipv4Setting::Manual == ipv6Setting->method()) { + QList ipv6AddressList = ipv6Setting->addresses(); + NetworkManager::IpAddress settingIpv6Address = ipv6AddressList.at(0); + if (settingIpv6Address.isValid()) { + ipv6Address = settingIpv6Address.ip().toString(); + } else { + qWarning()<<"[KyConnectResourse]"<<"get connect ipv6 failed, ipv6Address is not valid"; + } + } else { + qWarning()<<"[KyConnectResourse]"<<"get connect ipv6 failed, ipv6 config with dhcp"; + } + + return; +} + + +void KyConnectResourse::getIpv4ConnectSetting( + NetworkManager::Ipv4Setting::Ptr &ipv4Setting, + KyConnectSetting &connectSetting) +{ + if (NetworkManager::Ipv4Setting::Automatic == ipv4Setting->method()) { + connectSetting.m_ipv4ConfigIpType = CONFIG_IP_DHCP; + return; + } + + connectSetting.m_ipv4ConfigIpType = CONFIG_IP_MANUAL; + + connectSetting.m_ipv4Address = ipv4Setting->addresses(); + connectSetting.m_ipv4Dns = ipv4Setting->dns(); + + return; +} + +void KyConnectResourse::getIpv6ConnectSetting( + NetworkManager::Ipv6Setting::Ptr &ipv6Setting, + KyConnectSetting &connectSetting) +{ + + if (NetworkManager::Ipv6Setting::Automatic == ipv6Setting->method()) { + connectSetting.m_ipv6ConfigIpType = CONFIG_IP_DHCP; + return; + } + + connectSetting.m_ipv6ConfigIpType = CONFIG_IP_MANUAL; + + connectSetting.m_ipv6Address = ipv6Setting->addresses(); + + connectSetting.m_ipv6Dns = ipv6Setting->dns(); + + return; +} + +void KyConnectResourse::getConnectivity(NetworkManager::Connectivity &connectivity) +{ + m_networkResourceInstance->getConnectivity(connectivity); +} + +void KyConnectResourse::getConnectionSetting(QString connectUuid, KyConnectSetting &connectSetting) +{ + qDebug() <<"[KyConnectResourse]" << connectUuid <<"get connect setting info, connect uuid"; + + NetworkManager::Connection::Ptr connectPtr = + m_networkResourceInstance->getConnect(connectUuid); + + if (nullptr == connectPtr + || !connectPtr->isValid()) { + qWarning() <<"[KyConnectResourse]" << "it can not find valid connection" << connectUuid; + return; + } + + connectSetting.m_connectName = connectPtr->name(); + + NetworkManager::ConnectionSettings::Ptr connectionSettings = connectPtr->settings(); + connectSetting.m_ifaceName = connectionSettings->interfaceName(); + connectSetting.m_isAutoConnect = connectionSettings->autoconnect(); + + NetworkManager::Ipv4Setting::Ptr ipv4Setting = connectionSettings->setting(NetworkManager::Setting::Ipv4).dynamicCast(); + getIpv4ConnectSetting(ipv4Setting, connectSetting); + + NetworkManager::Ipv6Setting::Ptr ipv6Setting = connectionSettings->setting(NetworkManager::Setting::Ipv6).dynamicCast(); + getIpv6ConnectSetting(ipv6Setting, connectSetting); + + return; +} + +bool KyConnectResourse::getInterfaceByUuid(QString &deviceName, const QString connUuid) +{ + deviceName.clear(); + NetworkManager::Connection::Ptr connectPtr = + m_networkResourceInstance->getConnect(connUuid); + + if (nullptr == connectPtr) { + qWarning()<<"getInterfaceByUuid failed, connect uuid"<settings(); + + if (connectSettingPtr.isNull()) { + qWarning()<<"getInterfaceByUuid failed, connect uuid"<settings()->interfaceName(); + qDebug() << "getInterfaceByUuid success " << deviceName; + return true; +} + +void KyConnectResourse::getVpnConnectData(NetworkManager::ConnectionSettings::Ptr settingsPtr, + KyVpnConnectItem *vpnItem) +{ + NetworkManager::VpnSetting::Ptr vpnSetting = settingsPtr->setting(NetworkManager::Setting::Vpn).dynamicCast(); + NMStringMap vpnDataMap = vpnSetting->data(); + if (vpnDataMap.isEmpty()) { + qWarning()<<"get vpn connection Data failed, the data is empty"; + return; + } + + vpnItem->m_vpnGateWay = vpnDataMap["gateway"]; + vpnItem->m_vpnUser = vpnDataMap["user"]; + if ( "yes" == vpnDataMap["require-mppe"]) { + vpnItem->m_vpnMppe = true; + } else { + vpnItem->m_vpnMppe = false; + qDebug()<<"vpn mppe required:"<< vpnDataMap["require-mppe"]; + } + + return; +} + +KyVpnConnectItem *KyConnectResourse::getVpnConnectItem(NetworkManager::Connection::Ptr connectPtr) +{ + if (nullptr == connectPtr) { + qWarning()<<"[KyConnectResourse]"<<"get vpn connection item failed, the connect is empty"; + return nullptr; + } + + KyVpnConnectItem *vpnItem = new KyVpnConnectItem(); + NetworkManager::ConnectionSettings::Ptr settingPtr = connectPtr->settings(); + + vpnItem->m_vpnName = connectPtr->name(); + vpnItem->m_vpnUuid = connectPtr->uuid(); + vpnItem->m_vpnState = NetworkManager::VpnConnection::State::Disconnected; + + getConnectIp(settingPtr, vpnItem->m_vpnIpv4Address, vpnItem->m_vpnIpv6Address); + getVpnConnectData(settingPtr, vpnItem); + + return vpnItem; +} + +void KyConnectResourse::getVpnConnections(QList &vpnConnectItemList) +{ + int index = 0; + NetworkManager::Connection::List connectList; + + qDebug()<<"[KyConnectResourse]"<<"get vpn connections"; + + connectList.clear(); + connectList = m_networkResourceInstance->getConnectList(); + + if (connectList.empty()) { + qWarning()<<"[KyConnectResourse]"<<"get vpn connections failed, the connect list is empty"; + return; + } + + NetworkManager::Connection::Ptr connectPtr = nullptr; + for (index = 0; index < connectList.size(); index++) { + connectPtr = connectList.at(index); + if (connectPtr.isNull()) { + continue; + } + + if (NetworkManager::ConnectionSettings::ConnectionType::Vpn + != connectPtr->settings()->connectionType()) { + qDebug()<<"[KyConnectResourse]"<<"connect name:" << connectPtr->name() + <<"connect type:"<settings()->connectionType(); + continue; + } + + if (m_networkResourceInstance->isActiveConnection(connectPtr->uuid())) { + qDebug()<<"[KyConnectResourse]"<name()<<"is active connection"; + continue; + } + + KyVpnConnectItem *connectItem = getVpnConnectItem(connectPtr); + if (nullptr != connectItem) { + vpnConnectItemList << connectItem; + //connectItem->dumpInfo(); + } + + connectPtr = nullptr; + } + + return; +} + + +KyBluetoothConnectItem *KyConnectResourse::getBluetoothConnectItem(NetworkManager::Connection::Ptr connectPtr) +{ + if (nullptr == connectPtr) { + qWarning()<<"[KyConnectResourse]"<<"get bluetooth connection item failed, the connect is empty"; + return nullptr; + } + + KyBluetoothConnectItem *bluetoothItem = new KyBluetoothConnectItem(); + bluetoothItem->m_connectName = connectPtr->name(); + bluetoothItem->m_connectUuid = connectPtr->uuid(); + bluetoothItem->m_state = NetworkManager::ActiveConnection::State::Deactivated; + + NetworkManager::ConnectionSettings::Ptr settingPtr = connectPtr->settings(); + getConnectIp(settingPtr, bluetoothItem->m_ipv4Address, bluetoothItem->m_ipv6Address); + + NetworkManager::BluetoothSetting::Ptr bluetoothSetting = + settingPtr->setting(NetworkManager::Setting::Bluetooth).dynamicCast(); + bluetoothItem->m_deviceAddress = bluetoothSetting->bluetoothAddress(); + QByteArray btAddrArray = bluetoothSetting->bluetoothAddress(); + for (int index = 0; index < btAddrArray.size(); ++index) { + qDebug("bt address %d %s", index, btAddrArray[index]); + } + // qDebug()<<"bt address 0:"<< btAddrArray[0]; + // qDebug()<<"bt address 1:"<< btAddrArray[1]; + // qDebug()<<"array size:"<m_deviceAddress.toInt(nullptr, 16); + + return bluetoothItem; +} + +void KyConnectResourse::getBluetoothConnections(QList &bluetoothConnectItemList) +{ + int index = 0; + NetworkManager::Connection::List connectList; + + qDebug()<<"[KyConnectResourse]"<<"get bluetooth connections"; + + connectList.clear(); + connectList = m_networkResourceInstance->getConnectList(); + + if (connectList.empty()) { + qWarning()<<"[KyConnectResourse]"<<"get bluetooth connections failed, the connect list is empty"; + return; + } + + NetworkManager::Connection::Ptr connectPtr = nullptr; + for (index = 0; index < connectList.size(); index++) { + connectPtr = connectList.at(index); + if (connectPtr.isNull()) { + continue; + } + + if (NetworkManager::ConnectionSettings::ConnectionType::Bluetooth + != connectPtr->settings()->connectionType()) { + qDebug()<<"[KyConnectResourse]"<<"connect name:" << connectPtr->name() + <<"connect type:"<settings()->connectionType(); + continue; + } + + if (m_networkResourceInstance->isActiveConnection(connectPtr->uuid())) { + qDebug()<<"[KyConnectResourse]"<name()<<"is active connection"; + continue; + } + + KyBluetoothConnectItem *connectItem = getBluetoothConnectItem(connectPtr); + if (nullptr != connectItem) { + bluetoothConnectItemList << connectItem; + //connectItem->dumpInfo(); + } + + connectPtr = nullptr; + } + + return; +} + + +KyApConnectItem *KyConnectResourse::getApConnectItem(NetworkManager::Connection::Ptr connectPtr) +{ + if (nullptr == connectPtr) { + qWarning()<<"[KyConnectResourse]"<<"get bluetooth connection item failed, the connect is empty"; + return nullptr; + } + + NetworkManager::ConnectionSettings::Ptr settingPtr = connectPtr->settings(); + NetworkManager::WirelessSetting::Ptr wirelessSetting + = settingPtr->setting(NetworkManager::Setting::Wireless).dynamicCast(); + + if (NetworkManager::WirelessSetting::NetworkMode::Ap + != wirelessSetting->mode()) { + qDebug() << "[KyConnectResourse]" <<"get ap item failed, the active connect mode is not ap."; + return nullptr; + } + + KyNetworkDeviceResourse deviceResource; + if (!deviceResource.wirelessDeviceIsExist(settingPtr->interfaceName())) { + qDebug() << "[KyConnectResourse]" <<"get ap item failed, the ap device is not exist yet"; + return nullptr; + } + + QByteArray rawSsid = wirelessSetting->ssid(); + + KyApConnectItem *apConnectItem = new KyApConnectItem(); + apConnectItem->m_connectName = connectPtr->name(); + apConnectItem->m_connectSsid = getSsidFromByteArray(rawSsid); + apConnectItem->m_connectUuid = connectPtr->uuid(); + if (wirelessSetting->band() == NetworkManager::WirelessSetting::FrequencyBand::A) { + apConnectItem->m_band = str2GBand; + } else if (wirelessSetting->band() == NetworkManager::WirelessSetting::FrequencyBand::Bg) { + apConnectItem->m_band = str5GBand; + } + apConnectItem->m_ifaceName = settingPtr->interfaceName(); + apConnectItem->m_isActivated = m_networkResourceInstance->isActiveConnection(connectPtr->uuid()); + + //NetworkManager::WirelessSecuritySetting::Ptr wirelessSecuritySetting + // = settingPtr->setting(NetworkManager::Setting::WirelessSecurity).dynamicCast(); + KyWirelessConnectOperation wirelessOperation; + apConnectItem->m_password = wirelessOperation.getPsk(apConnectItem->m_connectUuid);// wirelessSecuritySetting->psk(); + + return apConnectItem; +} + +KyApConnectItem *KyConnectResourse::getApConnectionByUuid(QString connectUuid) +{ + NetworkManager::Connection::Ptr connectPtr = nullptr; + + connectPtr = m_networkResourceInstance->getConnect(connectUuid); + if (nullptr == connectPtr) { + return nullptr; + } + + if (NetworkManager::ConnectionSettings::ConnectionType::Wireless + != connectPtr->settings()->connectionType()) { + return nullptr; + } + + KyApConnectItem *connectItem = getApConnectItem(connectPtr); + + return connectItem; +} + +void KyConnectResourse::getApConnections(QList &apConnectItemList) +{ + QList apActiveConnectItemList; + QList apDeactiveConnectItemList; + int index = 0; + NetworkManager::Connection::List connectList; + + qDebug()<<"[KyConnectResourse]"<<"get ap connections"; + + connectList.clear(); + connectList = m_networkResourceInstance->getConnectList(); + + if (connectList.empty()) { + qWarning()<<"[KyConnectResourse]"<<"get ap connections failed, the connect list is empty"; + return; + } + + NetworkManager::Connection::Ptr connectPtr = nullptr; + for (index = 0; index < connectList.size(); index++) { + connectPtr = connectList.at(index); + if (NetworkManager::ConnectionSettings::ConnectionType::Wireless + != connectPtr->settings()->connectionType()) { + qDebug()<<"[KyConnectResourse]"<<"connect name:" << connectPtr->name() + <<"connect type:"<settings()->connectionType(); + continue; + } + + KyApConnectItem *connectItem = getApConnectItem(connectPtr); + if (nullptr != connectItem) { + if (connectItem->m_isActivated) { + apActiveConnectItemList << connectItem; + } else { + apDeactiveConnectItemList << connectItem; + } + } + + connectPtr = nullptr; + } + + apConnectItemList << apActiveConnectItemList << apDeactiveConnectItemList; + + return; +} + + +bool KyConnectResourse::isWiredConnection(QString uuid) +{ + NetworkManager::Connection::Ptr connectPtr = + m_networkResourceInstance->getConnect(uuid); + if (connectPtr.isNull()) { + qWarning()<<"[KyConnectResourse]"<<"can not find wired connection"<path(); + QString connectionType = getConnectTypeByDbus(connectPath); + if (ETHERNET_TYPE == connectionType) { + return true; + } + + return false; +} + +bool KyConnectResourse::isWirelessConnection(QString uuid) +{ + NetworkManager::Connection::Ptr connectPtr = + m_networkResourceInstance->getConnect(uuid); + if (connectPtr.isNull()) { + qWarning()<<"[KyConnectResourse]"<<"can not find wireless connection"<isValid()) { + NetworkManager::ConnectionSettings::Ptr connectSettingPtr = connectPtr->settings(); + + if (connectSettingPtr.isNull()) { + qWarning()<<"[KyConnectResourse]"<<"get connect setting failed, connect uuid"<settings()->connectionType()) { + return true; + } + } + + return false; +} + +bool KyConnectResourse::isActivatedConnection(QString uuid) +{ + return m_networkResourceInstance->isActiveConnection(uuid); +} + +bool KyConnectResourse::isApConnection(QString uuid) +{ + NetworkManager::Connection::Ptr connectPtr = nullptr; + + connectPtr = m_networkResourceInstance->getConnect(uuid); + if (nullptr == connectPtr) { + return false; + } + + if (NetworkManager::ConnectionSettings::ConnectionType::Wireless + != connectPtr->settings()->connectionType()) { + return false; + } + + NetworkManager::ConnectionSettings::Ptr settingPtr = connectPtr->settings(); + NetworkManager::WirelessSetting::Ptr wirelessSetting + = settingPtr->setting(NetworkManager::Setting::Wireless).dynamicCast(); + if (NetworkManager::WirelessSetting::NetworkMode::Ap + != wirelessSetting->mode()) { + return false; + } + + return true; +} diff --git a/src/backend/dbus-interface/kylinconnectresource.h b/src/backend/dbus-interface/kylinconnectresource.h new file mode 100644 index 00000000..f79024ae --- /dev/null +++ b/src/backend/dbus-interface/kylinconnectresource.h @@ -0,0 +1,69 @@ +#ifndef KYLINCONNECTRESOURCE_H +#define KYLINCONNECTRESOURCE_H + +#include +#include "kylinnetworkresourcemanager.h" +#include "kylinconnectitem.h" +#include "kylinvpnconnectitem.h" +#include "kylinbluetoothconnectitem.h" +#include "kylinnetworkdeviceresource.h" +#include "kylinconnectsetting.h" +#include "kylinapconnectitem.h" + +class KyConnectResourse : public QObject +{ + Q_OBJECT +public: + explicit KyConnectResourse(QObject *parent = nullptr); + ~KyConnectResourse(); + +public: + KyConnectItem *getConnectionItemByUuid(QString connectUuid); + KyConnectItem *getConnectionItemByUuid(QString connectUuid, QString deviceName); + void getConnectionList(QString deviceName, + NetworkManager::ConnectionSettings::ConnectionType connectionType, + QList &connectItemList); + // void getWiredConnections(QList &wiredConnectItemList); + void getVpnConnections(QList &vpnConnectItemList); + void getBluetoothConnections(QList &bluetoothConnectItemList); + void getApConnections(QList &apConnectItemList); + KyApConnectItem *getApConnectionByUuid(QString connectUuid); + + void getConnectionSetting(QString connectUuid, KyConnectSetting &connectSetting); + bool getInterfaceByUuid(QString &deviceName, const QString connUuid); + void getConnectivity(NetworkManager::Connectivity &connectivity); + + bool isWiredConnection(QString uuid); + bool isWirelessConnection(QString uuid); + bool isActivatedConnection(QString uuid); + bool isApConnection(QString uuid); + +private: + bool isActiveDevice(QString conUuid, QString devName); + KyConnectItem *getConnectionItem(NetworkManager::Connection::Ptr connectPtr, QString devName); + void getConnectIp(NetworkManager::ConnectionSettings::Ptr settingPtr, + QString &ipv4Address, + QString &ipv6Address); +// KyWiredConnectItem *getWiredConnectItem(NetworkManager::Connection::Ptr connectPtr); + + void getVpnConnectData(NetworkManager::ConnectionSettings::Ptr settingPtr, + KyVpnConnectItem *vpnItem); + KyVpnConnectItem *getVpnConnectItem(NetworkManager::Connection::Ptr connectPtr); + KyBluetoothConnectItem *getBluetoothConnectItem(NetworkManager::Connection::Ptr connectPtr); + KyApConnectItem *getApConnectItem(NetworkManager::Connection::Ptr connectPtr); + + void getIpv4ConnectSetting(NetworkManager::Ipv4Setting::Ptr &ipv4Setting, + KyConnectSetting &connectSetting); + void getIpv6ConnectSetting(NetworkManager::Ipv6Setting::Ptr &ipv6Setting, + KyConnectSetting &connectSetting); + +signals: + void connectionAdd(QString uuid); + void connectionUpdate(QString uuid); + void connectionRemove(QString path); + void connectivityChanged(NetworkManager::Connectivity connectivity); + +private: + KyNetworkResourceManager *m_networkResourceInstance = nullptr; +}; +#endif // KYLINCONNECTRESOURCE_H diff --git a/src/backend/dbus-interface/kylinconnectsetting.cpp b/src/backend/dbus-interface/kylinconnectsetting.cpp new file mode 100644 index 00000000..88aeb57d --- /dev/null +++ b/src/backend/dbus-interface/kylinconnectsetting.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * 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, 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 + +KyConnectSetting::KyConnectSetting(/*QObject *parent) : QObject(parent*/) +{ + m_connectName = ""; + m_ifaceName = ""; + + m_ipv4ConfigIpType = CONFIG_IP_DHCP; + m_ipv4Address.clear(); + m_ipv4Dns.clear(); + + m_ipv6ConfigIpType = CONFIG_IP_DHCP; + m_ipv6Address.clear(); + m_ipv6Dns.clear(); + + m_isAutoConnect = true; +} + +KyConnectSetting::~KyConnectSetting() +{ + +} + +void KyConnectSetting::setIfaceName(QString &ifaceName) +{ + m_ifaceName = ifaceName; +} + +void KyConnectSetting::setConnectName(QString &connectName) +{ + m_connectName = connectName; +} + +int KyConnectSetting::setIpConfigType(KyIpAddressType ipType, KyIpConfigType ipConfigType) +{ + if (ipType != IPADDRESS_V4 && ipType != IPADDRESS_V6) { + qWarning()<<"set config ip type failed, the ip address type undefined"< +#include +//#include + +#include +#include +#include +#include +#include + +typedef enum { + CONFIG_IP_MANUAL, + CONFIG_IP_DHCP, +}KyIpConfigType; + +typedef enum { + IPADDRESS_V4, + IPADDRESS_V6, +}KyIpAddressType; + +class KyConnectSetting/* : public QObject*/ +{ +// Q_OBJECT +public: +/* explicit*/ KyConnectSetting(/*QObject *parent = nullptr*/); + ~KyConnectSetting(); + +public: + void setIfaceName(QString &ifaceName); + void setConnectName(QString &connectName); + int setIpConfigType(KyIpAddressType ipType, KyIpConfigType configType); + void ipv4AddressConstruct(QString &ipv4Address, QString &ipv4NetMask, QString &ipv4GateWay, QStringList &ipv4Dns); + void ipv6AddressConstruct(QString &ipv6Address, QString &ipv6NetMask, QString &ipv6GateWay, QStringList &ipv6Dns); + void dumpInfo(); + +public: + QString m_connectName; + QString m_ifaceName; + + KyIpConfigType m_ipv4ConfigIpType; + QList m_ipv4Address; + QList m_ipv4Dns; + + KyIpConfigType m_ipv6ConfigIpType; + QList m_ipv6Address; + QList m_ipv6Dns; + + bool m_isAutoConnect; +}; + +#endif // KYLINCONNECTSETTING_H diff --git a/src/backend/dbus-interface/kylinnetworkdeviceresource.cpp b/src/backend/dbus-interface/kylinnetworkdeviceresource.cpp new file mode 100644 index 00000000..d6d3ebdc --- /dev/null +++ b/src/backend/dbus-interface/kylinnetworkdeviceresource.cpp @@ -0,0 +1,310 @@ + +#include "kylinnetworkdeviceresource.h" +#include "kywirelessnetitem.h" + +#define VIRTURAL_DEVICE_PATH "/sys/devices/virtual/net" +#define LOG_FLAG "KyNetworkDeviceResourse" + +KyNetworkDeviceResourse::KyNetworkDeviceResourse(QObject *parent) : QObject(parent) +{ + m_networkResourceInstance = KyNetworkResourceManager::getInstance(); + + m_deviceMap.clear(); + + initDeviceMap(); + + connect(m_networkResourceInstance, &KyNetworkResourceManager::deviceAdd, + this, &KyNetworkDeviceResourse::onDeviceAdd, Qt::ConnectionType::DirectConnection); + connect(m_networkResourceInstance, &KyNetworkResourceManager::deviceRemove, + this, &KyNetworkDeviceResourse::onDeviceRemove, Qt::ConnectionType::DirectConnection); + connect(m_networkResourceInstance, &KyNetworkResourceManager::deviceUpdate, + this, &KyNetworkDeviceResourse::onDeviceUpdate, Qt::ConnectionType::DirectConnection); + + connect(m_networkResourceInstance, &KyNetworkResourceManager::deviceCarrierChanage, + this, &KyNetworkDeviceResourse::carrierChanage); + connect(m_networkResourceInstance, &KyNetworkResourceManager::deviceBitRateChanage, + this, &KyNetworkDeviceResourse::deviceBitRateChanage); + connect(m_networkResourceInstance, &KyNetworkResourceManager::deviceMacAddressChanage, + this, &KyNetworkDeviceResourse::deviceMacAddressChanage); + connect(m_networkResourceInstance, &KyNetworkResourceManager::deviceActiveChanage, + this, &KyNetworkDeviceResourse::deviceActiveChanage); + +} + +KyNetworkDeviceResourse::~KyNetworkDeviceResourse() +{ + m_networkResourceInstance = nullptr; +} + +void KyNetworkDeviceResourse::initDeviceMap() +{ + NetworkManager::Device::List deviceList + = m_networkResourceInstance->getNetworkDeviceList(); + + if (deviceList.isEmpty()) { + qDebug() << LOG_FLAG << "there is not interface in computer."; + return; + } + + NetworkManager::Device::Ptr devicePtr = nullptr; + for (int index = 0; index < deviceList.size(); ++index) { + devicePtr = deviceList.at(index); + if (devicePtr.isNull()) { + continue; + } + + m_deviceMap.insert(devicePtr->uni(), devicePtr->interfaceName()); + } + + return; +} + +void KyNetworkDeviceResourse::getNetworkDeviceList( + NetworkManager::Device::Type deviceType, + QStringList &networkDeviceList) +{ + NetworkManager::Device::List deviceList + = m_networkResourceInstance->getNetworkDeviceList(); + + if (deviceList.isEmpty()) { + qDebug() << LOG_FLAG <<"network device is not exist. device type" << deviceType; + return; + } + + NetworkManager::Device::Ptr devicePtr = nullptr; + for (int index = 0; index < deviceList.size(); ++index) { + devicePtr = deviceList.at(index); + if (devicePtr.isNull()) { + continue; + } + + if (devicePtr->type() == deviceType) { + if (NetworkManager::Device::Type::Ethernet == deviceType) { + //为了区分有线网卡和虚拟网卡 + qDebug()<< LOG_FLAG << "device uni" << devicePtr->udi(); + if (devicePtr->udi().startsWith(VIRTURAL_DEVICE_PATH)) { + continue; + } + } + + networkDeviceList<interfaceName(); + } + } + + return; +} + +void KyNetworkDeviceResourse::getHardwareInfo(QString ifaceName, QString &hardAddress, int &bandWith) +{ + NetworkManager::Device::Ptr connectDevice = + m_networkResourceInstance->getNetworkDevice(ifaceName); + + if (nullptr == connectDevice || !connectDevice->isValid()) { + qWarning()<< LOG_FLAG <<"get hardware info failed, the device" << ifaceName << "is not existed"; + hardAddress.clear(); + bandWith = 0; + return; + } + + switch (connectDevice->type()) { + case NetworkManager::Device::Ethernet: + { + NetworkManager::WiredDevice *wiredDevicePtr = + qobject_cast(connectDevice.data()); + hardAddress = wiredDevicePtr->hardwareAddress(); + bandWith = wiredDevicePtr->bitRate(); + break; + } + case NetworkManager::Device::Wifi: + { + NetworkManager::WirelessDevice *wirelessDevicePtr = + qobject_cast(connectDevice.data()); + hardAddress = wirelessDevicePtr->hardwareAddress(); + bandWith = wirelessDevicePtr->bitRate(); + break; + } + default: + { + hardAddress = ""; + bandWith = 0; + qWarning()<< LOG_FLAG << "the network device type is undefined" << connectDevice->type(); + break; + } + } + + return; +} + +NetworkManager::Device::State KyNetworkDeviceResourse::getDeviceState(QString deviceName) +{ + NetworkManager::Device::Ptr connectDevice = + m_networkResourceInstance->findDeviceInterface(deviceName); + if (!connectDevice.isNull() && connectDevice->isValid()) { + return connectDevice->state(); + } + + qWarning()<< LOG_FLAG <<"get device state failed, the device is " << deviceName; + + return NetworkManager::Device::State::UnknownState; +} + +bool KyNetworkDeviceResourse::wiredDeviceIsCarriered(QString deviceName) +{ + NetworkManager::Device::Ptr connectDevice = + m_networkResourceInstance->findDeviceInterface(deviceName); + if (connectDevice.isNull()) { + qDebug()<< LOG_FLAG << "check device carriered failed."; + return false; + } + + + if (connectDevice->isValid() + && NetworkManager::Device::Type::Ethernet == connectDevice->type()) { + NetworkManager::WiredDevice *wiredDevicePtr = + qobject_cast(connectDevice.data()); + return wiredDevicePtr->carrier(); + } + + qWarning()<< LOG_FLAG << deviceName <<" can not get carrier state."; + + return false; +} + +void KyNetworkDeviceResourse::setDeviceRefreshRate(QString deviceName, int ms) +{ + NetworkManager::Device::Ptr connectDevice = + m_networkResourceInstance->findDeviceInterface(deviceName); + if (connectDevice.isNull()) { + return; + } + + if (connectDevice->isValid()) { + NetworkManager::DeviceStatistics::Ptr deviceStatistics = connectDevice->deviceStatistics(); + deviceStatistics->setRefreshRateMs(ms); + } + + return; +} + +void KyNetworkDeviceResourse::getDeviceActiveAPInfo(const QString devName, QString &strMac, uint &iHz, uint &iChan, QString &secuType) +{ + strMac.clear(); + iHz = 0; + iChan = 0; + secuType.clear(); + + NetworkManager::Device::Ptr connectDevice = + m_networkResourceInstance->getNetworkDevice(devName); + + if (nullptr == connectDevice || !connectDevice->isValid()) { + qWarning()<< LOG_FLAG <<"getDeviceActiveAPInfo failed, the device" << devName << "is not existed"; + return; + } + + switch (connectDevice->type()) { + case NetworkManager::Device::Wifi: + { + NetworkManager::WirelessDevice *wirelessDevicePtr = + qobject_cast(connectDevice.data()); + NetworkManager::AccessPoint::Ptr apPtr = wirelessDevicePtr->activeAccessPoint(); + if (apPtr.isNull()) { + break; + } + strMac = apPtr->hardwareAddress(); + iHz = apPtr->frequency(); + iChan = NetworkManager::findChannel(iHz); + NetworkManager::AccessPoint::Capabilities cap = apPtr->capabilities(); + NetworkManager::AccessPoint::WpaFlags wpaFlag = apPtr->wpaFlags(); + NetworkManager::AccessPoint::WpaFlags rsnFlag = apPtr->rsnFlags(); + secuType = enumToQstring(cap, wpaFlag, rsnFlag); + break; + } + case NetworkManager::Device::Ethernet: + break; + default: + break; + } + + return; +} + +int KyNetworkDeviceResourse::getWirelessDeviceCapability(const QString deviceName) +{ + NetworkManager::Device::Ptr connectDevice = + m_networkResourceInstance->findDeviceInterface(deviceName); + if (connectDevice->isValid() + && NetworkManager::Device::Type::Wifi == connectDevice->type()) { + NetworkManager::WirelessDevice *wirelessDevicePtr = + qobject_cast(connectDevice.data()); + + int cap = 0; + if (wirelessDevicePtr->wirelessCapabilities() & NetworkManager::WirelessDevice::ApCap) { + cap = cap | 0x01; + } + if (wirelessDevicePtr->wirelessCapabilities() & NetworkManager::WirelessDevice::Freq2Ghz) { + cap = cap | 0x02; + } + if (wirelessDevicePtr->wirelessCapabilities() & NetworkManager::WirelessDevice::Freq5Ghz) { + cap = cap | 0x04; + } + return cap; + } else { + qWarning()<<"[KyNetworkDeviceResourse]"<findDeviceInterface(deviceName); + + if (devicePtr.isNull()) { + qDebug() << LOG_FLAG << "check device type failed, it is not exist"; + return false; + } + + if (NetworkManager::Device::Type::Ethernet == devicePtr->type() + && !devicePtr->udi().startsWith(VIRTURAL_DEVICE_PATH)) { + return true; + } + + return false; +} diff --git a/src/backend/dbus-interface/kylinnetworkdeviceresource.h b/src/backend/dbus-interface/kylinnetworkdeviceresource.h new file mode 100644 index 00000000..e3283c6c --- /dev/null +++ b/src/backend/dbus-interface/kylinnetworkdeviceresource.h @@ -0,0 +1,55 @@ +#ifndef KYLINNETORKDEVICERESOURCE_H +#define KYLINNETORKDEVICERESOURCE_H + +#include +#include "kylinnetworkresourcemanager.h" +#include "kylinconnectitem.h" +#include "kylinwiredconnectoperation.h" + +class KyNetworkDeviceResourse : public QObject +{ + Q_OBJECT +public: + explicit KyNetworkDeviceResourse(QObject *parent = nullptr); + ~KyNetworkDeviceResourse(); + +signals: + void deviceAdd(QString deviceName, NetworkManager::Device::Type deviceType); + void deviceRemove(QString deviceName); + void deviceUpdate(QString deviceName); + + void deviceNameUpdate(QString oldName, QString newName); + void stateChange(QString deviceName, int state); + + void carrierChanage(QString deviceName, bool pluged); + void deviceBitRateChanage(QString deviceName, int bitRate); + void deviceMacAddressChanage(QString deviceName, const QString &hwAddress); + void deviceActiveChanage(QString deviceName, bool deivceActive); + +public slots: + void onDeviceAdd(QString deviceName, QString uni, NetworkManager::Device::Type deviceType); + void onDeviceRemove(QString deviceName, QString uni); + void onDeviceUpdate(QString interface, QString dbusPath); + +public: + void getNetworkDeviceList(NetworkManager::Device::Type deviceType, QStringList &networkDeviceList); + void getHardwareInfo(QString ifaceName, QString &hardAddress, int &bandWith); + void getDeviceActiveAPInfo(const QString devName, QString &strMac, uint &iHz, uint &iChan, QString &secuType); + int getWirelessDeviceCapability(const QString deviceName); + NetworkManager::Device::State getDeviceState(QString deviceName); + + bool wiredDeviceIsCarriered(QString deviceName); + bool wirelessDeviceIsExist(const QString devName); + bool deviceIsWired(QString deviceName); + + void setDeviceRefreshRate(QString deviceName, int ms); + +private: + KyWiredConnectOperation wiredOperation; + KyNetworkResourceManager *m_networkResourceInstance = nullptr; + QStringList m_activeConnectUuidList; + QMap m_deviceMap; + + void initDeviceMap(); +}; +#endif // KYLINNETORKDEVICERESOURCE_H diff --git a/src/backend/dbus-interface/kylinnetworkresourcemanager.cpp b/src/backend/dbus-interface/kylinnetworkresourcemanager.cpp new file mode 100644 index 00000000..a6c2ada7 --- /dev/null +++ b/src/backend/dbus-interface/kylinnetworkresourcemanager.cpp @@ -0,0 +1,1019 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * 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, 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 +#include +#include "kylinutil.h" + +#define SIGNAL_DELAY 80000 +#define EMIT_DELAY 10000 + +#define LOG_FLAG "[KyNetworkResourceManager]" + +KyNetworkResourceManager* KyNetworkResourceManager::m_pInstance = nullptr; + +KyNetworkResourceManager* KyNetworkResourceManager::getInstance() +{ + if (m_pInstance == NULL) { + m_pInstance = new KyNetworkResourceManager(); + } + return m_pInstance; +} + +void KyNetworkResourceManager::Release() +{ + if (m_pInstance != NULL) { + delete m_pInstance; + m_pInstance = NULL; + } +} + +KyNetworkResourceManager::KyNetworkResourceManager(QObject *parent) : QObject(parent) +{ + qRegisterMetaType("NetworkManager::ActiveConnection::State"); + qRegisterMetaType("NetworkManager::Connectivity"); + qRegisterMetaType("NetworkManager::ActiveConnection::Reason"); + qRegisterMetaType("NetworkManager::Device::Type"); + + QDBusConnection::systemBus().connect(QString("org.freedesktop.DBus"), + QString("/org/freedesktop/DBus"), + QString("org.freedesktop.DBus"), + QString("NameOwnerChanged"), this, SLOT(onServiceAppear(QString,QString,QString))); +} + +void KyNetworkResourceManager::onInitNetwork() +{ + insertActiveConnections(); + insertConnections(); + insertDevices(); + insertWifiNetworks(); + + //initialize NetworkManager signals + connect(NetworkManager::notifier(), &NetworkManager::Notifier::deviceAdded, this, &KyNetworkResourceManager::onDeviceAdded); + connect(NetworkManager::notifier(), &NetworkManager::Notifier::deviceRemoved, this, &KyNetworkResourceManager::onDeviceRemoved); + connect(NetworkManager::notifier(), &NetworkManager::Notifier::activeConnectionAdded, this, &KyNetworkResourceManager::onActiveConnectionAdded); + connect(NetworkManager::notifier(), &NetworkManager::Notifier::activeConnectionRemoved, this, &KyNetworkResourceManager::onActiveConnectionRemoved); + connect(NetworkManager::settingsNotifier(), &NetworkManager::SettingsNotifier::connectionAdded, this, &KyNetworkResourceManager::onConnectionAdded); + connect(NetworkManager::settingsNotifier(), &NetworkManager::SettingsNotifier::connectionRemoved, this, static_cast(&KyNetworkResourceManager::onConnectionRemoved)); + + connect(NetworkManager::notifier(), &NetworkManager::Notifier::connectivityChanged, this, &KyNetworkResourceManager::connectivityChanged); + //todo wifi开关信号 + connect(NetworkManager::notifier(), &NetworkManager::Notifier::wirelessEnabledChanged, this, &KyNetworkResourceManager::wifiEnabledChanged); + + // Note: the connectionRemoved is never emitted in case network-manager service stop, + // we need remove the connections manually. + connect(NetworkManager::notifier(), &NetworkManager::Notifier::serviceDisappeared, this, &KyNetworkResourceManager::clearConnections); + connect(NetworkManager::notifier(), &NetworkManager::Notifier::serviceDisappeared, this, &KyNetworkResourceManager::clearWifiNetworks); + + qDebug() <<"[KyNetworkResourceManager]" + << "active connections:" << m_activeConns.size() + << "connections:" << m_connections.size() + << "network device:" << m_devices.size(); + m_initFinished = true; + + return; +} + +KyNetworkResourceManager::~KyNetworkResourceManager() +{ + +} + +void KyNetworkResourceManager::removeActiveConnection(int pos) +{ + //active connections signals + NetworkManager::ActiveConnection::Ptr conn = m_activeConns.takeAt(pos); + conn->disconnect(this); +} + +void KyNetworkResourceManager::clearActiveConnections() +{ + while (0 < m_activeConns.size()) + removeActiveConnection(0); +} + +void KyNetworkResourceManager::addActiveConnection(NetworkManager::ActiveConnection::Ptr conn) +{ + m_activeConns.push_back(conn); +#if 0 + connect(conn.data(), &NetworkManager::ActiveConnection::connectionChanged, this, &KyNetworkResourceManager::onActiveConnectionUpdated); + connect(conn.data(), &NetworkManager::ActiveConnection::default4Changed, this, &KyNetworkResourceManager::onActiveConnectionUpdated); + connect(conn.data(), &NetworkManager::ActiveConnection::default6Changed, this, &KyNetworkResourceManager::onActiveConnectionUpdated); + connect(conn.data(), &NetworkManager::ActiveConnection::dhcp4ConfigChanged, this, &KyNetworkResourceManager::onActiveConnectionUpdated); + connect(conn.data(), &NetworkManager::ActiveConnection::dhcp6ConfigChanged, this, &KyNetworkResourceManager::onActiveConnectionUpdated); + connect(conn.data(), &NetworkManager::ActiveConnection::ipV4ConfigChanged, this, &KyNetworkResourceManager::onActiveConnectionUpdated); + connect(conn.data(), &NetworkManager::ActiveConnection::ipV6ConfigChanged, this, &KyNetworkResourceManager::onActiveConnectionUpdated); + connect(conn.data(), &NetworkManager::ActiveConnection::idChanged, this, &KyNetworkResourceManager::onActiveConnectionUpdated); + connect(conn.data(), &NetworkManager::ActiveConnection::typeChanged, this, &KyNetworkResourceManager::onActiveConnectionUpdated); + connect(conn.data(), &NetworkManager::ActiveConnection::masterChanged, this, &KyNetworkResourceManager::onActiveConnectionUpdated); + connect(conn.data(), &NetworkManager::ActiveConnection::specificObjectChanged, this, &KyNetworkResourceManager::onActiveConnectionUpdated); +#endif + //connect(conn.data(), &NetworkManager::ActiveConnection::stateChangedReason, this, &KyNetworkResourceManager::onActiveConnectionChangedReason); + connect(conn.data(), &NetworkManager::ActiveConnection::stateChanged, this, &KyNetworkResourceManager::onActiveConnectionChanged); +#if 0 + connect(conn.data(), &NetworkManager::ActiveConnection::vpnChanged, this, &KyNetworkResourceManager::onActiveConnectionUpdated); + connect(conn.data(), &NetworkManager::ActiveConnection::uuidChanged, this, &KyNetworkResourceManager::onActiveConnectionUpdated); + connect(conn.data(), &NetworkManager::ActiveConnection::devicesChanged, this, &KyNetworkResourceManager::onActiveConnectionUpdated); +#endif + if (conn->vpn()) { + connect(qobject_cast(conn.data()), &NetworkManager::VpnConnection::bannerChanged, this, &KyNetworkResourceManager::onActiveConnectionUpdated); + connect(qobject_cast(conn.data()), &NetworkManager::VpnConnection::stateChanged, this, &KyNetworkResourceManager::onVpnActiveConnectChanagedReason); + } +} + +void KyNetworkResourceManager::insertActiveConnections() +{ + for (auto const & conn : NetworkManager::activeConnections()) { + if (conn.isNull()) { + continue; + } + + addActiveConnection(conn); + } +} + +void KyNetworkResourceManager::removeConnection(int pos) +{ + //connections signals + QString path = m_connections.at(pos)->path(); + NetworkManager::Connection::Ptr conn = m_connections.takeAt(pos); + conn->disconnect(this); + emit connectionRemove(path); +} + +void KyNetworkResourceManager::clearConnections() +{ + while (0 < m_connections.size()) { + removeConnection(0); + } +} + +void KyNetworkResourceManager::addConnection(NetworkManager::Connection::Ptr conn) +{ + m_connections.push_back(conn); + + //connections signals + connect(conn.data(), &NetworkManager::Connection::updated, this, &KyNetworkResourceManager::onConnectionUpdated); + connect(conn.data(), &NetworkManager::Connection::removed, this, &KyNetworkResourceManager::onConnectionRemoved); +} + +void KyNetworkResourceManager::insertConnections() +{ + for (auto const & connectPtr : NetworkManager::listConnections()) { + if (connectPtr.isNull()) { + continue; + } + + if (connectPtr->name().isEmpty() || connectPtr->uuid().isEmpty()) { + qWarning() <<"[KyNetworkResourceManager]" << " the name of connection is empty."; + continue; + } + + addConnection(connectPtr); + } + + return; +} + +void KyNetworkResourceManager::removeDevice(int pos) +{ + //connections signals + NetworkManager::Device::Ptr device = m_devices.takeAt(pos); + device->disconnect(this); +} + +void KyNetworkResourceManager::clearDevices() +{ + while (0 < m_devices.size()) + removeDevice(0); +} + +void KyNetworkResourceManager::addDevice(NetworkManager::Device::Ptr device) +{ + m_devices.push_back(device); + //device signals +#if 0 + //connect(device.data(), &NetworkManager::Device::stateChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(device.data(), &NetworkManager::Device::activeConnectionChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(device.data(), &NetworkManager::Device::autoconnectChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(device.data(), &NetworkManager::Device::availableConnectionChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(device.data(), &NetworkManager::Device::availableConnectionAppeared, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(device.data(), &NetworkManager::Device::availableConnectionDisappeared, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(device.data(), &NetworkManager::Device::capabilitiesChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(device.data(), &NetworkManager::Device::dhcp4ConfigChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(device.data(), &NetworkManager::Device::dhcp6ConfigChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(device.data(), &NetworkManager::Device::driverChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(device.data(), &NetworkManager::Device::driverVersionChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(device.data(), &NetworkManager::Device::firmwareMissingChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(device.data(), &NetworkManager::Device::firmwareVersionChanged, this, &KyNetworkResourceManager::onDeviceUpdated); +#endif + connect(device.data(), &NetworkManager::Device::activeConnectionChanged, this, &KyNetworkResourceManager::onDeviceActiveChanage); + connect(device.data(), &NetworkManager::Device::interfaceNameChanged, this, &KyNetworkResourceManager::onDeviceUpdated); +#if 0 + connect(device.data(), &NetworkManager::Device::ipV4AddressChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(device.data(), &NetworkManager::Device::ipV4ConfigChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(device.data(), &NetworkManager::Device::ipV6ConfigChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(device.data(), &NetworkManager::Device::ipInterfaceChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(device.data(), &NetworkManager::Device::managedChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(device.data(), &NetworkManager::Device::physicalPortIdChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(device.data(), &NetworkManager::Device::mtuChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(device.data(), &NetworkManager::Device::nmPluginMissingChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(device.data(), &NetworkManager::Device::meteredChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(device.data(), &NetworkManager::Device::connectionStateChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(device.data(), &NetworkManager::Device::stateReasonChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + + connect(device.data(), &NetworkManager::Device::stateChanged, this, &KyNetworkResourceManager::onDeviceStateChanged); + connect(device.data(), &NetworkManager::Device::udiChanged, this, &KyNetworkResourceManager::onDeviceUpdated); +#endif + switch (device->type()) + { + case NetworkManager::Device::Ethernet: + connect(qobject_cast(device.data()), &NetworkManager::WiredDevice::bitRateChanged, this, &KyNetworkResourceManager::onDeviceBitRateChanage); + connect(qobject_cast(device.data()), &NetworkManager::WiredDevice::carrierChanged, this, &KyNetworkResourceManager::onDeviceCarrierChanage); + connect(qobject_cast(device.data()), &NetworkManager::WiredDevice::hardwareAddressChanged, this, &KyNetworkResourceManager::onDeviceMacAddressChanage); + // connect(qobject_cast(device.data()), &NetworkManager::WiredDevice::permanentHardwareAddressChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + break; + + case NetworkManager::Device::Wifi: +#if 0 + connect(qobject_cast(device.data()), &NetworkManager::WirelessDevice::bitRateChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(qobject_cast(device.data()), &NetworkManager::WirelessDevice::activeAccessPointChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(qobject_cast(device.data()), &NetworkManager::WirelessDevice::modeChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(qobject_cast(device.data()), &NetworkManager::WirelessDevice::wirelessCapabilitiesChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(qobject_cast(device.data()), &NetworkManager::WirelessDevice::hardwareAddressChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(qobject_cast(device.data()), &NetworkManager::WirelessDevice::permanentHardwareAddressChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(qobject_cast(device.data()), &NetworkManager::WirelessDevice::wirelessPropertiesChanged, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(qobject_cast(device.data()), &NetworkManager::WirelessDevice::accessPointAppeared, this, &KyNetworkResourceManager::onDeviceUpdated); + connect(qobject_cast(device.data()), &NetworkManager::WirelessDevice::accessPointDisappeared, this, &KyNetworkResourceManager::onDeviceUpdated); +#endif + connect(qobject_cast(device.data()), &NetworkManager::WirelessDevice::networkAppeared, this, &KyNetworkResourceManager::onWifiNetworkAppeared); + connect(qobject_cast(device.data()), &NetworkManager::WirelessDevice::networkDisappeared, this, &KyNetworkResourceManager::onWifiNetworkDisappeared); + break; + default: + //TODO: other device types! + break; + } +} + +void KyNetworkResourceManager::insertDevices() +{ + for (auto const & device : NetworkManager::networkInterfaces()) { + if (device.isNull()) { + continue; + } + + addDevice(device); + } + + return; +} + +void KyNetworkResourceManager::removeWifiNetwork(int pos) +{ + //network signals + NetworkManager::WirelessNetwork::Ptr net = m_wifiNets.takeAt(pos); + net->disconnect(this); +} + +void KyNetworkResourceManager::clearWifiNetworks() +{ + while (0 < m_wifiNets.size()) + removeWifiNetwork(0); +} + +void KyNetworkResourceManager::addWifiNetwork(NetworkManager::WirelessNetwork::Ptr net) +{ + m_wifiNets.push_back(net); + //device signals + connect(net.data(), &NetworkManager::WirelessNetwork::signalStrengthChanged, this, &KyNetworkResourceManager::onUpdateWirelessNet); + connect(net.data(), &NetworkManager::WirelessNetwork::referenceAccessPointChanged, this, &KyNetworkResourceManager::onUpdateWirelessNet); + connect(net.data(), &NetworkManager::WirelessNetwork::disappeared, this, &KyNetworkResourceManager::onUpdateWirelessNet); +} + +void KyNetworkResourceManager::insertWifiNetworks() +{ + for (auto const & device : m_devices) { + if (device.isNull()) { + continue; + } + + if (NetworkManager::Device::Wifi == device->type()) { + NetworkManager::WirelessDevice::Ptr w_dev = device.objectCast(); + for (auto const & net : w_dev->networks()) { + if (!net.isNull()) { + addWifiNetwork(net); + emit wifiNetworkAdded(device->interfaceName(),net->ssid()); + } + } + } + } +} + +NetworkManager::ActiveConnection::Ptr KyNetworkResourceManager::findActiveConnection(QString const & path) +{ + auto i = std::find_if(m_activeConns.cbegin(), m_activeConns.cend(), [&path] (NetworkManager::ActiveConnection::Ptr const & conn) -> bool { + return conn->path() == path; + }); + return m_activeConns.cend() == i ? NetworkManager::ActiveConnection::Ptr{} : *i; +} + +template +NetworkManager::Device::Ptr KyNetworkResourceManager::findDevice(Predicate const & pred) +{ + auto i = std::find_if(m_devices.cbegin(), m_devices.cend(), pred); + return m_devices.cend() == i ? NetworkManager::Device::Ptr{} : *i; +} + +NetworkManager::Device::Ptr KyNetworkResourceManager::findDeviceUni(QString const & uni) +{ + return findDevice([&uni] (NetworkManager::Device::Ptr const & dev) { return dev->uni() == uni; }); +} + +NetworkManager::Device::Ptr KyNetworkResourceManager::findDeviceInterface(QString const & interfaceName) +{ + return findDevice([&interfaceName] (NetworkManager::Device::Ptr const & dev) { return dev->interfaceName() == interfaceName; }); +} + +NetworkManager::WirelessNetwork::Ptr KyNetworkResourceManager::findWifiNetwork(QString const & ssid, QString const & devUni) +{ + auto i = std::find_if(m_wifiNets.cbegin(), m_wifiNets.cend(), [&ssid, &devUni] (NetworkManager::WirelessNetwork::Ptr const & net) -> bool { + return net->ssid() == ssid && net->device() == devUni; + }); + return m_wifiNets.cend() == i ? NetworkManager::WirelessNetwork::Ptr{} : *i; +} + +NetworkManager::Device::Ptr KyNetworkResourceManager::getNetworkDevice(const QString ifaceName) +{ + NetworkManager::Device::Ptr devicePtr = nullptr; + if (ifaceName.isEmpty()) { + return nullptr; + } + + for (int index = 0; index < m_devices.size(); ++index) { + devicePtr = m_devices.at(index); + if (devicePtr.isNull()) { + continue; + } + + if (ifaceName == devicePtr->interfaceName()) { + return devicePtr; + } + } + + return nullptr; +} + +NetworkManager::ActiveConnection::Ptr KyNetworkResourceManager::getActiveConnect(const QString activeConnectUuid) +{ + int index = 0; + NetworkManager::ActiveConnection::Ptr activateConnectPtr = nullptr; + + qDebug()<<"[KyNetworkResourceManager]"<<"get activetate connect with uuid"<< activeConnectUuid; + if (activeConnectUuid.isEmpty()) { + return nullptr; + } + + for (index = 0; index < m_activeConns.size(); ++index) { + activateConnectPtr = m_activeConns.at(index); + if (activateConnectPtr.isNull()) { + continue; + } + + if (activateConnectPtr->uuid() == activeConnectUuid) { + return activateConnectPtr; + } + } + + qWarning()<<"[KyNetworkResourceManager]"<<"it can not find the activate connect with uuid" <uuid() == connectUuid) { + return connectPtr; + } + } + + qWarning()<<"[KyNetworkResourceManager]"<<"it can not find connect with uuid"<uuid() == uuid + && NetworkManager::ActiveConnection::State::Activated == activateConnectPtr->state()) { + return true; + } + } + + return false; +} + +bool KyNetworkResourceManager::isActivatingConnection(QString uuid) +{ + int index = 0; + NetworkManager::ActiveConnection::Ptr activateConnectPtr = nullptr; + + if (uuid.isEmpty()) { + return false; + } + + for (index = 0; index < m_activeConns.size(); ++index) { + activateConnectPtr = m_activeConns.at(index); + if (activateConnectPtr.isNull()) { + continue; + } + + if (activateConnectPtr->uuid() == uuid + && NetworkManager::ActiveConnection::State::Activating == activateConnectPtr->state()) { + return true; + } + } + + return false; +} + +void KyNetworkResourceManager::getConnectivity(NetworkManager::Connectivity &connectivity) +{ + connectivity = NetworkManager::connectivity(); +} + +bool KyNetworkResourceManager::NetworkManagerIsInited() +{ + return m_initFinished; +} + +void KyNetworkResourceManager::requestScan(NetworkManager::WirelessDevice * dev) +{ + if (nullptr == dev) { + qWarning() << LOG_FLAG << "request scan failed, wireless device is invalid."; + return; + } + + qDebug() <<"[KyNetworkResourceManager]"<< dev->interfaceName()<<"start scan wifi ap"; + QDBusPendingReply<> reply = dev->requestScan(); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, dev); + connect(watcher, &QDBusPendingCallWatcher::finished, [dev] (QDBusPendingCallWatcher * watcher) { + if (watcher->isError() || !watcher->isValid()) + { + //TODO: in what form should we output the warning messages + qWarning() << QStringLiteral("requestScan on device '%1' failed: %3").arg(dev->interfaceName()) + .arg(watcher->error().message()); + } + watcher->deleteLater(); + }); + + return; +} + +void KyNetworkResourceManager::onServiceAppear(QString interface, QString oldOwner, QString newOwner) +{ + if (interface == "org.freedesktop.NetworkManager" + && oldOwner.isEmpty() && !newOwner.isEmpty()) { + qDebug() << LOG_FLAG << "org.freedesktop.NetworkManager start"; + QTimer::singleShot(500,this,&KyNetworkResourceManager::insertWifiNetworks); + } +} + +void KyNetworkResourceManager::onConnectionUpdated() +{ + NetworkManager::Connection *connectPtr = + qobject_cast(sender()); + if (nullptr != connectPtr && connectPtr->isValid()) { + qDebug()<< LOG_FLAG <<"connection will Update, connection name"<name() + << "connection uuid" << connectPtr->uuid(); + emit connectionUpdate(connectPtr->uuid()); + } else { + qWarning()<< LOG_FLAG + <<"onConnectionUpdate failed, the connect is invalid"; + } + + return; +} + +void KyNetworkResourceManager::onActiveConnectionUpdated() +{ + //emit activeConnectionUpdate(qobject_cast(sender())); +} + +void KyNetworkResourceManager::onActiveConnectionChangedReason( + NetworkManager::ActiveConnection::State state, + NetworkManager::ActiveConnection::Reason reason) +{ + NetworkManager::ActiveConnection * activeConnect = + qobject_cast(sender()); + if (nullptr != activeConnect && activeConnect->isValid()) { + qDebug()<< LOG_FLAG <<"connect uuid"<uuid() + <<"state change"<uuid(), state, reason); + } else { + qWarning() << LOG_FLAG << "onActiveConnectionChangedReason failed, the connection is invalid."; + } + + return; +} + +void KyNetworkResourceManager::onActiveConnectionChanged( + NetworkManager::ActiveConnection::State state) +{ + NetworkManager::ActiveConnection * activeConnect = + qobject_cast(sender()); + if (nullptr != activeConnect && activeConnect->isValid()) { + qDebug()<< LOG_FLAG << "connection uuid" << activeConnect->uuid() + <<"state change "<state() != state) { + qDebug() << "[KyNetworkResourceManager]" + <<"connect real state"<state() <<"change state"<uuid(), state, + NetworkManager::ActiveConnection::Reason::UknownReason); + } else { + qWarning() << LOG_FLAG << "onActiveConnectionChanged failed, the connection is invalid."; + } + + return; +} + +void KyNetworkResourceManager::onVpnActiveConnectChanagedReason(NetworkManager::VpnConnection::State state, + NetworkManager::VpnConnection::StateChangeReason reason) +{ + NetworkManager::ActiveConnection *activeConnect = + qobject_cast(sender()); + + if (nullptr != activeConnect && activeConnect->isValid()) { + qDebug()<<"vpn connect uuid" << activeConnect->uuid() + <<"state change " <uuid(), state, reason); + } else { + qWarning() << LOG_FLAG << "onVpnActiveConnectChanagedReason failed, the connection is invalid."; + } + + return; +} + +void KyNetworkResourceManager::onDeviceActiveChanage() +{ + NetworkManager::Device *p_device = qobject_cast(sender()); + if (nullptr == p_device) { + return; + } + + QString deviceName = p_device->interfaceName(); + //此处需要取反,因为激活连接的网卡状态是false,断开连接的网卡状态是true + bool isActive = !p_device->isActive(); + + qDebug()<< LOG_FLAG << "device active change, device name " << deviceName + << "active state" << isActive; + + emit deviceActiveChanage(deviceName, isActive); + + return; +} + +void KyNetworkResourceManager::onDeviceUpdated() +{ + NetworkManager::Device *p_device = qobject_cast(sender()); + if (nullptr == p_device) { + return; + } + + QString deviceName = p_device->interfaceName(); + QString deviceUni = p_device->uni(); + + emit deviceUpdate(deviceName, deviceUni); + + return; +} + +void KyNetworkResourceManager::onDeviceCarrierChanage(bool pluged) +{ + NetworkManager::WiredDevice * networkDevice + = qobject_cast(sender()); + + qDebug()<< LOG_FLAG<<"device carrier chanage"<< pluged; + if (nullptr !=networkDevice && networkDevice->isValid()) { + emit deviceCarrierChanage(networkDevice->interfaceName(), pluged); + } else { + qWarning()<< LOG_FLAG<<"onDeviceCarrierChanage failed."; + } + + return; +} + +void KyNetworkResourceManager::onDeviceBitRateChanage(int bitRate) +{ + NetworkManager::WiredDevice * networkDevice + = qobject_cast(sender()); + + if (nullptr != networkDevice + && networkDevice->isValid()) { + emit deviceBitRateChanage(networkDevice->interfaceName(), bitRate); + } else { + qWarning()<< LOG_FLAG <<"the device is not invalid with bitrate" << bitRate; + } + + return; +} + +void KyNetworkResourceManager::onDeviceMacAddressChanage(const QString &hwAddress) +{ + NetworkManager::WiredDevice * networkDevice + = qobject_cast(sender()); + + if (nullptr !=networkDevice && networkDevice->isValid()) { + emit deviceMacAddressChanage(networkDevice->interfaceName(), hwAddress); + } else { + qWarning()<< LOG_FLAG <<"the device is not invalid with mac" << hwAddress; + } + + return; +} + +void KyNetworkResourceManager::onDeviceStateChanged( + NetworkManager::Device::State newstate, + NetworkManager::Device::State oldstate, + NetworkManager::Device::StateChangeReason reason) +{ + qWarning() << LOG_FLAG <<"the device state "<interfaceName() << ssid; + + NetworkManager::WirelessDevice * w_dev = qobject_cast(dev); + NetworkManager::WirelessNetwork::Ptr net = w_dev->findNetwork(ssid); + if (!net.isNull()) { + if (0 > m_wifiNets.indexOf(net)){ + addWifiNetwork(net); + } else { + //TODO: onWifiNetworkUpdate + qDebug()<< LOG_FLAG << "add but already exist"; + } + + NetworkManager::AccessPoint::Ptr accessPoitPtr = net->referenceAccessPoint(); + QByteArray rawSsid = accessPoitPtr->rawSsid(); + QString wifiSsid = getSsidFromByteArray(rawSsid); + emit wifiNetworkAdded(dev->interfaceName(), wifiSsid); + } + + return; +} + +void KyNetworkResourceManager::onWifiNetworkUpdate(NetworkManager::WirelessNetwork * net) +{ + if (nullptr == net) { + return; + } + + auto index = std::find(m_wifiNets.cbegin(), m_wifiNets.cend(), net); + if (m_wifiNets.cend() != index) { + if (net->accessPoints().isEmpty()) { + //emit + bool bFlag = false; + QString devIface; + NetworkManager::Device::Ptr dev = findDeviceUni(net->device()); + if(dev.isNull()) { + qDebug()<< LOG_FLAG << "device invalid"; + bFlag = true; + } else { + devIface = dev->interfaceName(); + } + + //remove + auto pos = index - m_wifiNets.cbegin(); + removeWifiNetwork(pos); + if(bFlag) { + //device invalid + qDebug() << LOG_FLAG << "wifiNetworkDeviceDisappear"; + emit wifiNetworkDeviceDisappear(); + } else { + qDebug()<< LOG_FLAG << "wifiNetwork disappear" << net << net->ssid(); + NetworkManager::AccessPoint::Ptr accessPoitPtr = net->referenceAccessPoint(); + QByteArray rawSsid = accessPoitPtr->rawSsid(); + QString wifiSsid = getSsidFromByteArray(rawSsid); + emit wifiNetworkRemoved(devIface, wifiSsid); + } + } else { + qDebug()<< LOG_FLAG << "wifiNetworkPropertyChange " << net << net->ssid(); + emit wifiNetworkPropertyChange(net); + } + } + + return; +} + +void KyNetworkResourceManager::onWifiNetworkRemove(NetworkManager::Device * dev, QString const & ssid) +{ + if (nullptr == dev) { + return; + } + + qDebug() << "wifiNetworkRemove" << dev << dev->interfaceName() << ssid; + + NetworkManager::WirelessNetwork::Ptr net = findWifiNetwork(ssid, dev->uni()); + if (!net.isNull()) { + auto pos = m_wifiNets.indexOf(net); + if (0 <= pos) { + removeWifiNetwork(pos); + NetworkManager::AccessPoint::Ptr accessPoitPtr = net->referenceAccessPoint(); + QByteArray rawSsid = accessPoitPtr->rawSsid(); + QString wifiSsid = getSsidFromByteArray(rawSsid); + emit wifiNetworkRemoved(dev->interfaceName(), wifiSsid); + } + } + + return; +} + +void KyNetworkResourceManager::onWifiNetworkAppeared(QString const & ssid) +{ + NetworkManager::Device * p_device = qobject_cast(sender()); + if (nullptr != p_device) { + onWifiNetworkAdd(p_device, ssid); + + QString deviceName = p_device->interfaceName(); + QString deviceUni = p_device->uni(); + + emit deviceUpdate(deviceName, deviceUni); + } else { + qWarning()<< LOG_FLAG << "onWifiNetworkAppeared failed."; + } + + return; +} + +void KyNetworkResourceManager::onWifiNetworkDisappeared(QString const & ssid) +{ + NetworkManager::Device *p_device = qobject_cast(sender()); + if (nullptr != p_device) { + onWifiNetworkRemove(p_device, ssid); + + QString deviceName = p_device->interfaceName(); + QString deviceUni = p_device->uni(); + + emit deviceUpdate(deviceName, deviceUni); + } else { + qWarning()<< LOG_FLAG << "onWifiNetworkDisappeared failed."; + } + + return; +} + +void KyNetworkResourceManager::onUpdateWirelessNet() +{ + NetworkManager::WirelessNetwork *p_wirelessNet = + qobject_cast(sender()); + if (nullptr != p_wirelessNet) { + onWifiNetworkUpdate(p_wirelessNet); + } + + return; +} + +void KyNetworkResourceManager::onDeviceAdded(QString const & uni) +{ + qDebug()<< "onDeviceAdded"<isValid()) { + qWarning() << uni << " is currently not invalid"; + return; + } + + if (0 > m_devices.indexOf(networkDevice)) { + addDevice(networkDevice); + emit deviceAdd(networkDevice->interfaceName(), networkDevice->uni(), networkDevice->type()); + } else { + qWarning() << networkDevice->interfaceName() <<"the device is exist in network device list."; + } + + return; +} + +void KyNetworkResourceManager::onDeviceRemoved(QString const & uni) +{ + NetworkManager::Device::Ptr networkDevice = findDeviceUni(uni); + if (networkDevice.isNull()) { + qWarning()<<"the device is not exist in network device list ."<< uni; + return; + } + + qDebug()<<"remove network device"<< networkDevice->interfaceName() <<"uni:" << uni; + + auto index = std::find(m_devices.cbegin(), m_devices.cend(), networkDevice); + if (m_devices.cend() != index) { + const int pos = index - m_devices.cbegin(); + removeDevice(pos); + emit deviceRemove(networkDevice->interfaceName(), networkDevice->uni()); + } + + return; +} + +void KyNetworkResourceManager::onActiveConnectionAdded(QString const & path) +{ + NetworkManager::ActiveConnection::Ptr activeConnectPtr = NetworkManager::findActiveConnection(path); + if (activeConnectPtr.isNull()) { + qWarning() << "[KyNetworkResourceManager]" << "the active connect is null, so do not add it."<isValid()) { + qWarning() << "[KyNetworkResourceManager]" << path << " connect is currently not valid"; + return; + } + + qDebug()<<"add active connect"<connection()->name(); + + if (0 > m_activeConns.indexOf(activeConnectPtr)) { + addActiveConnection(activeConnectPtr); + emit activeConnectionAdd(activeConnectPtr->uuid()); + } else { + //TODO: onActiveConnectionUpdate + qWarning() << "[KyNetworkResourceManager]" << "update active connection to do"; + //emit activeConnectionUpdate(conn->uuid()); + } + + return; +} + +void KyNetworkResourceManager::onActiveConnectionRemoved(QString const & path) +{ + NetworkManager::ActiveConnection::Ptr activeConnectPtr = findActiveConnection(path);//XXX: const QString &uni + if (activeConnectPtr.isNull()) { + qWarning() <<"[KyNetworkResourceManager]" + <<"the active connect is null, so do not remove it. "<< path; + return; + } + + qDebug() <<"[KyNetworkResourceManager]"<<"remove active connect"<uuid(); + + auto index = std::find(m_activeConns.cbegin(), m_activeConns.cend(), activeConnectPtr); + if (m_activeConns.cend() != index) { + const int pos = index - m_activeConns.cbegin(); + removeActiveConnection(pos); + emit activeConnectionRemove(activeConnectPtr->uuid()); + } + + return; +} + +void KyNetworkResourceManager::onConnectionAdded(QString const & path) +{ + NetworkManager::Connection::Ptr connectPtr = NetworkManager::findConnection(path); + if (connectPtr.isNull()) { + qWarning() <<"[KyNetworkResourceManager]" <<"it can not find in networkmanager."<isValid()) { + qWarning() <<"[KyNetworkResourceManager]" << path << " is currently not invalid"; + return; + } + + qDebug() <<"[KyNetworkResourceManager]" <<"add connect "<< connectPtr->name() << connectPtr->path(); + + if (connectPtr->name().isEmpty() || connectPtr->uuid().isEmpty()) { + qWarning() <<"[KyNetworkResourceManager]" << "the name or uuid of connection is empty"; + return; + } + + if (0 > m_connections.indexOf(connectPtr)) { + addConnection(connectPtr); + emit connectionAdd(connectPtr->uuid()); + } else { + //TODO::updateconnect + qWarning() << "[KyNetworkResourceManager]" << connectPtr->uuid() <<" connect is exist in connect list."; + } + + return; +} + +void KyNetworkResourceManager::onConnectionRemoved(QString const & path) +{ + if (path.isEmpty()) { + qDebug() <<"[KyNetworkResourceManager]" <<"the connect path is empty"; + return; + } + + qDebug() <<"[KyNetworkResourceManager]" << "remove connection path" << path; + NetworkManager::Connection::Ptr connectionPtr = nullptr; + for (int index = 0; index < m_connections.size(); ++index) { + connectionPtr = m_connections.at(index); + if (connectionPtr->path() == path) { + removeConnection(index); + return; + } + } + + qWarning() <<"[KyNetworkResourceManager]" << path <<" connect is no exist in connect list"; + + return; +} + +void KyNetworkResourceManager::removeConnection(QString const & uuid) +{ + NetworkManager::Connection::Ptr conn = this->getConnect(uuid); + if(!conn.isNull()) { + conn->disconnect(this); + conn->remove(); + } +} + +void KyNetworkResourceManager::setWirelessNetworkEnabled(bool enabled) +{ + NetworkManager::setWirelessEnabled(enabled); +} + +void KyNetworkResourceManager::connectionDump() +{ + NetworkManager::Connection::Ptr connectionPtr = nullptr; + for (int index = 0; index < m_connections.size(); ++index) { + connectionPtr = m_connections.at(index); + qDebug()<<"connection info**********************"; + qDebug()<<"connection name"<< connectionPtr->name(); + qDebug()<<"connection uuid"<< connectionPtr->uuid(); + qDebug()<<"connection path"<< connectionPtr->path(); + } +} diff --git a/src/backend/dbus-interface/kylinnetworkresourcemanager.h b/src/backend/dbus-interface/kylinnetworkresourcemanager.h new file mode 100644 index 00000000..14e4ec27 --- /dev/null +++ b/src/backend/dbus-interface/kylinnetworkresourcemanager.h @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * 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, 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class KyNetworkResourceManager : public QObject +{ + Q_OBJECT +public: + static KyNetworkResourceManager* getInstance(); + static void Release(); + +public: + explicit KyNetworkResourceManager(QObject *parent = nullptr); + ~KyNetworkResourceManager(); + + void removeActiveConnection(int pos); + void clearActiveConnections(); + void insertActiveConnections(); + void addActiveConnection(NetworkManager::ActiveConnection::Ptr conn); + + void removeConnection(int pos); + void clearConnections(); + void insertConnections(); + void addConnection(NetworkManager::Connection::Ptr conn); + + void removeDevice(int pos); + void clearDevices(); + void insertDevices(); + void addDevice(NetworkManager::Device::Ptr conn); + + void removeWifiNetwork(int pos); + void clearWifiNetworks(); + void addWifiNetwork(NetworkManager::WirelessNetwork::Ptr net); + + NetworkManager::ActiveConnection::Ptr findActiveConnection(QString const & path); + template + NetworkManager::Device::Ptr findDevice(Predicate const & pred); + NetworkManager::Device::Ptr findDeviceUni(QString const & uni); + NetworkManager::Device::Ptr findDeviceInterface(QString const & interfaceName); + NetworkManager::WirelessNetwork::Ptr findWifiNetwork(QString const & ssid, QString const & devUni); + + void requestScan(NetworkManager::WirelessDevice * dev); + + void removeConnection(QString const & uuid); + + void connectionDump(); + +public: + NetworkManager::Device::Ptr getNetworkDevice(const QString ifaceName); + NetworkManager::ActiveConnection::Ptr getActiveConnect(const QString activeConnectUuid); + NetworkManager::Connection::Ptr getConnect(const QString uuid); + NetworkManager::WirelessNetwork::Ptr getWifiNetwork(const QString apName); + + NetworkManager::ActiveConnection::List getActiveConnectList(); + NetworkManager::Connection::List getConnectList(); + NetworkManager::Device::List getNetworkDeviceList(); + bool isActiveConnection(QString uuid); + bool isActivatingConnection(QString uuid); + + void getConnectivity(NetworkManager::Connectivity &connectivity); + + bool NetworkManagerIsInited(); + +signals: + void connectionAdd(QString uuid); + void connectionUpdate(QString uuid); + void connectionRemove(QString path); + + void deviceAdd(QString deviceName, QString uni, NetworkManager::Device::Type deviceType); + void deviceUpdate(QString deviceName, QString deviceUni); + void deviceRemove(QString deviceName, QString uni); + + void deviceActiveChanage(QString deviceName, bool deviceActive); + void deviceCarrierChanage(QString deviceName, bool pluged); + void deviceBitRateChanage(QString deviceName, int bitRate); + void deviceMacAddressChanage(QString deviceName, const QString &hwAddress); + + //to KyWirelessNetResource + void wifiNetworkRemoved(QString, QString); + void wifiNetworkAdded(QString, QString); + void wifiNetworkPropertyChange(NetworkManager::WirelessNetwork * net); + void wifiNetworkDeviceDisappear(); + void wifiEnabledChanged(bool); + + void activeConnectionsReset(); + void activeConnectionAdd(QString uuid); + void activeConnectionUpdate(QString uuid); + void activeConnectionRemove(QString uuid); + void activeConnectStateChangeReason(QString uuid, + NetworkManager::ActiveConnection::State state, + NetworkManager::ActiveConnection::Reason reason); + void vpnActiveConnectStateChangeReason(QString uuid, + NetworkManager::VpnConnection::State state, + NetworkManager::VpnConnection::StateChangeReason reason); + + void connectivityChanged(NetworkManager::Connectivity connectivity); + +public slots: + void onInitNetwork(); + void setWirelessNetworkEnabled(bool enabled); + +private slots: + void insertWifiNetworks(); + void onServiceAppear(QString, QString, QString); + //connection + void onConnectionUpdated(); + //void onConnectionRemoved(); + + //active connection + void onActiveConnectionUpdated(); + void onActiveConnectionChangedReason(NetworkManager::ActiveConnection::State state, + NetworkManager::ActiveConnection::Reason reason); + + void onActiveConnectionChanged(NetworkManager::ActiveConnection::State state); + void onVpnActiveConnectChanagedReason(NetworkManager::VpnConnection::State state, + NetworkManager::VpnConnection::StateChangeReason reason); + + //device + + void onDeviceActiveChanage(); + + void onDeviceUpdated(); + void onDeviceCarrierChanage(bool pluged); + void onDeviceBitRateChanage(int bitRate); + void onDeviceMacAddressChanage(const QString &hwAddress); + void onDeviceStateChanged(NetworkManager::Device::State newstate, + NetworkManager::Device::State oldstate, + NetworkManager::Device::StateChangeReason reason); + + void onWifiNetworkAppeared(QString const & ssid); + void onWifiNetworkDisappeared(QString const & ssid); + + //wifi network + void onUpdateWirelessNet(); + + //notifier + void onDeviceAdded(QString const & uni); + void onDeviceRemoved(QString const & uni); + void onActiveConnectionAdded(QString const & path); + void onActiveConnectionRemoved(QString const & path); + + //settings notifier + void onConnectionAdded(QString const & path); + void onConnectionRemoved(QString const & path); + +private: + void onWifiNetworkAdd(NetworkManager::Device * dev, QString const & ssid); + void onWifiNetworkUpdate(NetworkManager::WirelessNetwork * net); + void onWifiNetworkRemove(NetworkManager::Device * dev, QString const & ssid); + +private: + bool m_initFinished = false; + +public: + static KyNetworkResourceManager* m_pInstance; + + NetworkManager::ActiveConnection::List m_activeConns; //已连接资源类 + NetworkManager::Connection::List m_connections; //配置文件资源类 + NetworkManager::Device::List m_devices; //设备类 + NetworkManager::WirelessNetwork::List m_wifiNets; //无线热点类 +}; + + +#endif // KYLINNETWORKRESOURCEMANAGER_H diff --git a/src/backend/dbus-interface/kylinutil.cpp b/src/backend/dbus-interface/kylinutil.cpp new file mode 100644 index 00000000..6fce5409 --- /dev/null +++ b/src/backend/dbus-interface/kylinutil.cpp @@ -0,0 +1,85 @@ +#include "kylinutil.h" +#include + +#define LOG_FLAG "[kylin-util]" + +QString getConnectTypeByDbus(QString &connectPath) +{ + QString connectType = ""; + + if (connectPath.isEmpty()) { + qWarning()<< LOG_FLAG << "connect path is empty, so can not get connect type"; + return connectType; + } + + QDBusInterface dbusInterface("org.freedesktop.NetworkManager", + connectPath, + "org.freedesktop.NetworkManager.Settings.Connection", + QDBusConnection::systemBus()); + + QDBusMessage result = dbusInterface.call("GetSettings"); + const QDBusArgument &dbusArg1st = result.arguments().at( 0 ).value(); + QMap> map; + dbusArg1st >> map; + + if (map.isEmpty()) { + qWarning() << LOG_FLAG <<"get connection settings failed."; + return connectType; + } + + QMap connectMap = map.value(KEY_CONNECTION); + if (connectMap.isEmpty()) { + qWarning() << LOG_FLAG <<"threre is not connection settings"; + return connectType; + } + + connectType = connectMap.value(KEY_CONNECT_TYPE).toString(); + +// qDebug() << LOG_FLAG << "connection type" << connectType; + + return connectType; + +} + +QString getSsidFromByteArray(QByteArray &rawSsid) +{ + QString wifiSsid = ""; + + if (rawSsid.isEmpty()) { + qWarning() << LOG_FLAG << "wifi raw ssid is empty"; + return wifiSsid; + } + + /* + * 由于区分GB2312和UTF-8的方法比较困难,加之会存在中英文混合的情况,所以暂时 + * 不区分,统一经过gb2312转换,经过测试没有影响。 + */ +// QTextCodec *p_textGBK = QTextCodec::codecForName("GB2312"); +// wifiSsid = p_textGBK->toUnicode(rawSsid); + + QTextCodec::ConverterState state; + QTextCodec *codec = QTextCodec::codecForName("UTF-8"); + codec->toUnicode( rawSsid.constData(), rawSsid.size(), &state); + if (state.invalidChars > 0) + { + wifiSsid = QTextCodec::codecForName("GBK")->toUnicode(rawSsid); + } + else + { + wifiSsid = rawSsid; + } + +// if (!QString::fromUtf8(rawSsid).contains("?")) { +// QTextCodec *p_textGBK = QTextCodec::codecForName("GB2312"); +// wifiSsid = p_textGBK->toUnicode(rawSsid); + +// qDebug() << LOG_FLAG <<"gb2312 to string ssid" << wifiSsid; +// //qDebug() << LOG_FLAG << "-------------> GB2312 " << byteArrayGB; +// } else { +// wifiSsid = QString::fromUtf8(rawSsid); + +// qDebug()<< LOG_FLAG <<" UTF-8 ssid: " < UTF-8 " << bytearray; +// } + return wifiSsid; +} diff --git a/src/backend/dbus-interface/kylinutil.h b/src/backend/dbus-interface/kylinutil.h new file mode 100644 index 00000000..08c980b8 --- /dev/null +++ b/src/backend/dbus-interface/kylinutil.h @@ -0,0 +1,20 @@ +#ifndef KYLINUTIL_H +#define KYLINUTIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#define KEY_CONNECTION "connection" +#define KEY_CONNECT_TYPE "type" +#define ETHERNET_TYPE "802-3-ethernet" + +QString getConnectTypeByDbus(QString &connectPath); +QString getSsidFromByteArray(QByteArray &rawSsid); + +#endif // KYLINUTIL_H diff --git a/src/backend/dbus-interface/kylinvpnconnectitem.cpp b/src/backend/dbus-interface/kylinvpnconnectitem.cpp new file mode 100644 index 00000000..7b770089 --- /dev/null +++ b/src/backend/dbus-interface/kylinvpnconnectitem.cpp @@ -0,0 +1,23 @@ + +#include "kylinvpnconnectitem.h" + + +KyVpnConnectItem::KyVpnConnectItem(QObject *parent) : QObject(parent) +{ + m_vpnName = ""; + m_vpnUuid = ""; + + m_vpnUser = ""; + m_vpnGateWay = ""; + + m_vpnIpv4Address = ""; + m_vpnIpv6Address = ""; + + m_vpnMppe = false; + m_vpnState = NetworkManager::VpnConnection::State::Disconnected; +} + +KyVpnConnectItem::~KyVpnConnectItem() +{ + +} diff --git a/src/backend/dbus-interface/kylinvpnconnectitem.h b/src/backend/dbus-interface/kylinvpnconnectitem.h new file mode 100644 index 00000000..e4340fbb --- /dev/null +++ b/src/backend/dbus-interface/kylinvpnconnectitem.h @@ -0,0 +1,30 @@ +#ifndef KYLINVPNCONNECTITEM_H +#define KYLINVPNCONNECTITEM_H + +#include +#include +#include + +class KyVpnConnectItem : public QObject +{ + Q_OBJECT +public: + explicit KyVpnConnectItem(QObject *parent = nullptr); + ~KyVpnConnectItem(); + +public: + QString m_vpnName; + QString m_vpnUuid; + + QString m_vpnUser; + QString m_vpnGateWay; + + QString m_vpnIpv4Address; + QString m_vpnIpv6Address; + + bool m_vpnMppe; + NetworkManager::VpnConnection::State m_vpnState; +}; + + +#endif // KYLINVPNCONNECTITEM_H diff --git a/src/backend/dbus-interface/kylinvpnrequest.c b/src/backend/dbus-interface/kylinvpnrequest.c new file mode 100644 index 00000000..c294bd66 --- /dev/null +++ b/src/backend/dbus-interface/kylinvpnrequest.c @@ -0,0 +1,762 @@ +#include "kylinvpnrequest.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "gsystem-local-alloc.h" +#include "nma-vpn-password-dialog.h" +#include "nm-macros-internal.h" + +extern char **environ; + +/*****************************************************************************/ + +typedef struct { + char *name; + char *label; + char *value; + gboolean is_secret; + gboolean should_ask; +} EuiSecret; + +typedef struct { + char *uuid; + char *id; + char *service_type; + + guint watch_id; + GPid pid; + + int child_stdout; + GString *child_response; + GIOChannel *channel; + guint channel_eventid; + GVariantBuilder secrets_builder; + gboolean external_ui_mode; + + /* These are just for the external UI mode */ + EuiSecret *eui_secrets; +} RequestData; + +typedef struct { + SecretsRequest req; + RequestData *req_data; +} VpnSecretsInfo; + + +gint +_nm_utils_ascii_str_to_bool (const char *str, + gint default_value) +{ + gsize len; + char *s = NULL; + + if (!str) + return default_value; + + while (str[0] && g_ascii_isspace (str[0])) + str++; + + if (!str[0]) + return default_value; + + len = strlen (str); + if (g_ascii_isspace (str[len - 1])) { + s = g_strdup (str); + g_strchomp (s); + str = s; + } + + if (!g_ascii_strcasecmp (str, "true") || !g_ascii_strcasecmp (str, "yes") || !g_ascii_strcasecmp (str, "on") || !g_ascii_strcasecmp (str, "1")) + default_value = TRUE; + else if (!g_ascii_strcasecmp (str, "false") || !g_ascii_strcasecmp (str, "no") || !g_ascii_strcasecmp (str, "off") || !g_ascii_strcasecmp (str, "0")) + default_value = FALSE; + if (s) + g_free (s); + return default_value; +} + + +/*****************************************************************************/ + +static void request_data_free (RequestData *req_data); +static void complete_request (VpnSecretsInfo *info); + +/*****************************************************************************/ + +size_t +applet_vpn_request_get_secrets_size (void) +{ + return sizeof (VpnSecretsInfo); +} + +/*****************************************************************************/ + +static void +external_ui_add_secrets (VpnSecretsInfo *info) +{ + RequestData *req_data = info->req_data; + EuiSecret *secret; + guint i; + + for (i = 0; req_data->eui_secrets[i].name; i++) { + secret = &req_data->eui_secrets[i]; + if ( secret->is_secret + && secret->value + && secret->value[0]) { + g_variant_builder_add (&req_data->secrets_builder, "{ss}", + secret->name, + secret->value); + } + } +} + +static void +external_ui_dialog_response (GtkDialog *dialog, int response_id, gpointer user_data) +{ + VpnSecretsInfo *info = user_data; + RequestData *req_data = info->req_data; + NMAVpnPasswordDialog *vpn_dialog = NMA_VPN_PASSWORD_DIALOG (dialog); + EuiSecret *secret; + const char *value; + guint i_secret, i_pw; + + for (i_secret = 0, i_pw = 0; req_data->eui_secrets[i_secret].name; i_secret++) { + secret = &req_data->eui_secrets[i_secret]; + if ( secret->is_secret + && secret->should_ask) { + switch (i_pw) { + case 0: + value = nma_vpn_password_dialog_get_password (vpn_dialog); + break; + case 1: + value = nma_vpn_password_dialog_get_password_secondary (vpn_dialog); + break; + case 2: + value = nma_vpn_password_dialog_get_password_ternary (vpn_dialog); + break; + default: + continue; + } + g_free (secret->value); + secret->value = g_strdup (value); + i_pw++; + } + } + + gtk_widget_destroy (GTK_WIDGET (dialog)); + external_ui_add_secrets (info); + complete_request (info); +} + +static gboolean +external_ui_from_child_response (VpnSecretsInfo *info, GError **error) +{ + RequestData *req_data = info->req_data; + gs_unref_keyfile GKeyFile *keyfile = NULL; + gs_strfreev char **groups = NULL; + NMAVpnPasswordDialog *dialog = NULL; + gs_free char *version = NULL; + gs_free char *title = NULL; + gs_free char *message = NULL; + gsize num_groups; + guint num_ask = 0; + guint i_group, i_secret, i_pw; + + /* Parse response key file */ + keyfile = g_key_file_new (); + + if (!g_key_file_load_from_data (keyfile, + req_data->child_response->str, + req_data->child_response->len, + G_KEY_FILE_NONE, + error)) { + return FALSE; + } + + groups = g_key_file_get_groups (keyfile, &num_groups); + if (g_strcmp0 (groups[0], "VPN Plugin UI") != 0) { + g_set_error_literal (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + "Expected [VPN Plugin UI]"); + return FALSE; + } + + version = g_key_file_get_string (keyfile, "VPN Plugin UI", "Version", error); + if (!version) + return FALSE; + if (strcmp (version, "2") != 0) { + g_set_error_literal (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + "Expected Version=2"); + return FALSE; + } + + title = g_key_file_get_string (keyfile, "VPN Plugin UI", "Title", error); + if (!title) + return FALSE; + + message = g_key_file_get_string (keyfile, "VPN Plugin UI", "Description", error); + if (!message) + return FALSE; + + /* Create a secret instance for each group */ + req_data->eui_secrets = g_new0 (EuiSecret, num_groups); + for (i_group = 1, i_secret = 0; i_group < num_groups; i_group++) { + EuiSecret *secret = &req_data->eui_secrets[i_secret]; + const char *group = groups[i_group]; + char *label; + + label = g_key_file_get_string (keyfile, group, "Label", NULL); + if (!label) { + g_warning ("Skipping entry: no label\n"); + continue; + } + + secret->name = g_strdup (group); + secret->label = label; + secret->value = g_key_file_get_string (keyfile, group, "Value", NULL); + secret->is_secret = g_key_file_get_boolean (keyfile, group, "IsSecret", NULL); + secret->should_ask = g_key_file_get_boolean (keyfile, group, "ShouldAsk", NULL); + + i_secret++; + + if (secret->is_secret && secret->should_ask) + num_ask++; + } + + /* If there are any secrets that must be asked to user, + * create a dialog and display it. */ + if (num_ask > 0) { + dialog = (NMAVpnPasswordDialog *) nma_vpn_password_dialog_new (title, message, NULL); + g_object_ref_sink (dialog); + + nma_vpn_password_dialog_set_show_password (dialog, FALSE); + nma_vpn_password_dialog_set_show_password_secondary (dialog, FALSE); + nma_vpn_password_dialog_set_show_password_ternary (dialog, FALSE); + + for (i_secret = 0, i_pw = 0; req_data->eui_secrets[i_secret].name; i_secret++) { + EuiSecret *secret = &req_data->eui_secrets[i_secret]; + + if ( secret->is_secret + && secret->should_ask) { + switch (i_pw) { + case 0: + nma_vpn_password_dialog_set_show_password (dialog, TRUE); + nma_vpn_password_dialog_set_password_label (dialog, secret->label); + if (secret->value) + nma_vpn_password_dialog_set_password (dialog, secret->value); + break; + case 1: + nma_vpn_password_dialog_set_show_password_secondary (dialog, TRUE); + nma_vpn_password_dialog_set_password_secondary_label (dialog, secret->label); + if (secret->value) + nma_vpn_password_dialog_set_password_secondary (dialog, secret->value); + break; + case 2: + nma_vpn_password_dialog_set_show_password_ternary (dialog, TRUE); + nma_vpn_password_dialog_set_password_ternary_label (dialog, secret->label); + if (secret->value) + nma_vpn_password_dialog_set_password_ternary (dialog, secret->value); + break; + default: + g_warning ("Skipping entry: more than 3 passwords not supported\n"); + continue; + } + i_pw++; + } + } + g_signal_connect (dialog, + "response", + G_CALLBACK (external_ui_dialog_response), + info); + gtk_widget_show (GTK_WIDGET (dialog)); + return TRUE; + } + + /* Nothing to ask, return known secrets */ + external_ui_add_secrets (info); + complete_request (info); + return TRUE; +} + +/*****************************************************************************/ + +static void +complete_request (VpnSecretsInfo *info) +{ + SecretsRequest *req = (SecretsRequest *) info; + RequestData *req_data = info->req_data; + GVariantBuilder settings_builder, vpn_builder; + gs_unref_variant GVariant *settings = NULL; + + g_variant_builder_init (&settings_builder, NM_VARIANT_TYPE_CONNECTION); + g_variant_builder_init (&vpn_builder, NM_VARIANT_TYPE_SETTING); + + g_variant_builder_add (&vpn_builder, "{sv}", + NM_SETTING_VPN_SECRETS, + g_variant_builder_end (&req_data->secrets_builder)); + g_variant_builder_add (&settings_builder, "{sa{sv}}", + NM_SETTING_VPN_SETTING_NAME, + &vpn_builder); + settings = g_variant_builder_end (&settings_builder); + + applet_secrets_request_complete (req, settings, NULL); + applet_secrets_request_free (req); +} + +static void +process_child_response (VpnSecretsInfo *info) +{ + SecretsRequest *req = (SecretsRequest *) info; + RequestData *req_data = info->req_data; + gs_free_error GError *error = NULL; + + if (req_data->external_ui_mode) { + if (!external_ui_from_child_response (info, &error)) { + applet_secrets_request_complete (req, NULL, error); + applet_secrets_request_free (req); + } + } else { + char **lines = g_strsplit (req_data->child_response->str, "\n", -1); + int i; + + for (i = 0; lines[i] && *(lines[i]); i += 2) { + if (lines[i + 1] == NULL) + break; + g_variant_builder_add (&req_data->secrets_builder, "{ss}", lines[i], lines[i + 1]); + } + + g_strfreev (lines); + complete_request (info); + } +} + +static void +child_finished_cb (GPid pid, int status, gpointer user_data) +{ + VpnSecretsInfo *info = user_data; + SecretsRequest *req = (SecretsRequest *) info; + RequestData *req_data = info->req_data; + gs_free_error GError *error = NULL; + + req_data->pid = 0; + req_data->watch_id = 0; + + if (status) { + error = g_error_new (NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_USER_CANCELED, + "%s.%d (%s): canceled", __FILE__, __LINE__, __func__); + + applet_secrets_request_complete (req, NULL, error); + applet_secrets_request_free (req); + } else if (req_data->channel_eventid == 0) { + /* We now have both the child response and its exit status. Process it. */ + process_child_response (info); + } +} + +static gboolean +child_stdout_data_cb (GIOChannel *source, GIOCondition condition, gpointer user_data) +{ + SecretsRequest *req = user_data; + VpnSecretsInfo *info = (VpnSecretsInfo *) req; + RequestData *req_data = info->req_data; + GIOStatus status; + char buf[4096]; + size_t bytes_read; + gs_free_error GError *error = NULL; + + status = g_io_channel_read_chars (source, buf, sizeof (buf)-1, &bytes_read, &error); + switch (status) { + case G_IO_STATUS_ERROR: + req_data->channel_eventid = 0; + applet_secrets_request_complete (req, NULL, error); + applet_secrets_request_free (req); + return FALSE; + case G_IO_STATUS_EOF: + req_data->channel_eventid = 0; + if (req_data->pid == 0) { + /* We now have both the childe respons and + * its exit status. Process it. */ + process_child_response (info); + } + return FALSE; + case G_IO_STATUS_NORMAL: + g_string_append_len (req_data->child_response, buf, bytes_read); + break; + default: + /* What just happened... */ + g_return_val_if_reached (FALSE); + } + + return TRUE; +} + +/*****************************************************************************/ + +static void +_str_append (GString *str, + const char *tag, + const char *val) +{ + const char *s; + gsize i; + + nm_assert (str); + nm_assert (tag && tag[0]); + nm_assert (val); + + g_string_append (str, tag); + g_string_append_c (str, '='); + + s = strchr (val, '\n'); + if (s) { + gs_free char *val2 = g_strdup (val); + + for (i = 0; val2[i]; i++) { + if (val2[i] == '\n') + val2[i] = ' '; + } + g_string_append (str, val2); + } else + g_string_append (str, val); + g_string_append_c (str, '\n'); +} + +static char * +connection_to_data (NMConnection *connection, + gsize *out_length, + GError **error) +{ + NMSettingVpn *s_vpn; + GString *buf; + const char **keys; + guint i, len; + + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + s_vpn = nm_connection_get_setting_vpn (connection); + if (!s_vpn) { + g_set_error_literal (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + ("Connection had no VPN setting")); + return NULL; + } + + buf = g_string_new_len (NULL, 100); + + keys = nm_setting_vpn_get_data_keys (s_vpn, &len); + for (i = 0; i < len; i++) { + _str_append (buf, "DATA_KEY", keys[i]); + _str_append (buf, "DATA_VAL", nm_setting_vpn_get_data_item (s_vpn, keys[i])); + } + nm_clear_g_free (&keys); + + keys = nm_setting_vpn_get_secret_keys (s_vpn, &len); + for (i = 0; i < len; i++) { + _str_append (buf, "SECRET_KEY", keys[i]); + _str_append (buf, "SECRET_VAL", nm_setting_vpn_get_secret (s_vpn, keys[i])); + } + nm_clear_g_free (&keys); + + g_string_append (buf, "DONE\n\nQUIT\n\n"); + NM_SET_OUT (out_length, buf->len); + return g_string_free (buf, FALSE); +} + +/*****************************************************************************/ + +static gboolean +connection_to_fd (NMConnection *connection, + int fd, + GError **error) +{ + gs_free char *data = NULL; + gsize data_len; + gssize w; + int errsv; + + data = connection_to_data (connection, &data_len, error); + if (!data) + return FALSE; + +again: + w = write (fd, data, data_len); + if (w < 0) { + errsv = errno; + if (errsv == EINTR) + goto again; + g_set_error (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + ("Failed to write connection to VPN UI: %s (%d)"), g_strerror (errsv), errsv); + return FALSE; + } + + if ((gsize) w != data_len) { + g_set_error_literal (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + ("Failed to write connection to VPN UI: incomplete write")); + return FALSE; + } + + return TRUE; +} + +/*****************************************************************************/ + +static void +vpn_child_setup (gpointer user_data) +{ + /* We are in the child process at this point */ + pid_t pid = getpid (); + setpgid (pid, pid); +} + +static gboolean +auth_dialog_spawn (const char *con_id, + const char *con_uuid, + const char *const*hints, + const char *auth_dialog, + const char *service_type, + gboolean supports_hints, + gboolean external_ui_mode, + guint32 flags, + GPid *out_pid, + int *out_stdin, + int *out_stdout, + GError **error) +{ + gsize hints_len; + gsize i, j; + gs_free const char **argv = NULL; + gs_free const char **envp = NULL; + gsize environ_len; + + g_return_val_if_fail (con_id, FALSE); + g_return_val_if_fail (con_uuid, FALSE); + g_return_val_if_fail (auth_dialog, FALSE); + g_return_val_if_fail (service_type, FALSE); + g_return_val_if_fail (out_pid, FALSE); + g_return_val_if_fail (out_stdin, FALSE); + g_return_val_if_fail (out_stdout, FALSE); + + hints_len = NM_PTRARRAY_LEN (hints); + argv = g_new (const char *, 11 + (2 * hints_len)); + i = 0; + argv[i++] = auth_dialog; + argv[i++] = "-u"; + argv[i++] = con_uuid; + argv[i++] = "-n"; + argv[i++] = con_id; + argv[i++] = "-s"; + argv[i++] = service_type; + if (flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION) + argv[i++] = "-i"; + if (flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW) + argv[i++] = "-r"; + for (j = 0; supports_hints && (j < hints_len); j++) { + argv[i++] = "-t"; + argv[i++] = hints[j]; + } + if (external_ui_mode) + argv[i++] = "--external-ui-mode"; + nm_assert (i <= 10 + (2 * hints_len)); + argv[i++] = NULL; + + environ_len = NM_PTRARRAY_LEN (environ); + envp = g_new (const char *, environ_len + 1); + memcpy (envp, environ, sizeof (const char *) * environ_len); + for (i = 0, j = 0; i < environ_len; i++) { + const char *e = environ[i]; + + if (g_str_has_prefix (e, "G_MESSAGES_DEBUG=")) { + /* skip this environment variable. We interact with the auth-dialog via stdout. + * G_MESSAGES_DEBUG may enable additional debugging messages from GTK. */ + continue; + } + envp[j++] = e; + } + envp[j] = NULL; + + if (!g_spawn_async_with_pipes (NULL, + (char **) argv, + (char **) envp, + G_SPAWN_DO_NOT_REAP_CHILD, + vpn_child_setup, + NULL, + out_pid, + out_stdin, + out_stdout, + NULL, + error)) + return FALSE; + + return TRUE; +} + +/*****************************************************************************/ + +static void +free_vpn_secrets_info (SecretsRequest *req) +{ + request_data_free (((VpnSecretsInfo *) req)->req_data); +} + +gboolean +applet_vpn_request_get_secrets (SecretsRequest *req, GError **error) +{ + VpnSecretsInfo *info = (VpnSecretsInfo *) req; + RequestData *req_data; + NMSettingConnection *s_con; + NMSettingVpn *s_vpn; + const char *connection_type; + const char *service_type; + const char *auth_dialog; + gs_unref_object NMVpnPluginInfo *plugin = NULL; + int child_stdin; + + applet_secrets_request_set_free_func (req, free_vpn_secrets_info); + + s_con = nm_connection_get_setting_connection (req->connection); + s_vpn = nm_connection_get_setting_vpn (req->connection); + + connection_type = nm_setting_connection_get_connection_type (s_con); + g_return_val_if_fail (nm_streq0 (connection_type, NM_SETTING_VPN_SETTING_NAME), FALSE); + + service_type = nm_setting_vpn_get_service_type (s_vpn); + g_return_val_if_fail (service_type, FALSE); + + plugin = nm_vpn_plugin_info_new_search_file (NULL, service_type); + auth_dialog = plugin ? nm_vpn_plugin_info_get_auth_dialog (plugin) : NULL; + if (!auth_dialog) { + g_set_error (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + "Could not find the authentication dialog for VPN connection type '%s'", + service_type); + return FALSE; + } + + info->req_data = g_slice_new0 (RequestData); + if (!info->req_data) { + g_set_error_literal (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + "Could not create VPN secrets request object"); + return FALSE; + } + req_data = info->req_data; + + g_variant_builder_init (&req_data->secrets_builder, G_VARIANT_TYPE ("a{ss}")); + + req_data->external_ui_mode = _nm_utils_ascii_str_to_bool ( + nm_vpn_plugin_info_lookup_property (plugin, + "GNOME", + "supports-external-ui-mode"), + FALSE); + + if (!auth_dialog_spawn (nm_setting_connection_get_id (s_con), + nm_setting_connection_get_uuid (s_con), + (const char *const*) req->hints, + auth_dialog, + service_type, + nm_vpn_plugin_info_supports_hints (plugin), + req_data->external_ui_mode, + req->flags, + &req_data->pid, + &child_stdin, + &req_data->child_stdout, + error)) + return FALSE; + + /* catch when child is reaped */ + req_data->watch_id = g_child_watch_add (req_data->pid, child_finished_cb, info); + + /* listen to what child has to say */ + req_data->channel = g_io_channel_unix_new (req_data->child_stdout); + req_data->child_response = g_string_sized_new (4096); + req_data->channel_eventid = g_io_add_watch (req_data->channel, + G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, + child_stdout_data_cb, + info); + + if (!connection_to_fd (req->connection, child_stdin, error)) + return FALSE; + close (child_stdin); + + g_io_channel_set_encoding (req_data->channel, NULL, NULL); + + /* Dump parts of the connection to the child */ + return TRUE; +} + +/*****************************************************************************/ + +static gboolean +ensure_killed (gpointer data) +{ + pid_t pid = GPOINTER_TO_INT (data); + + if (kill (pid, 0) == 0) + kill (pid, SIGKILL); + /* ensure the child is reaped */ + waitpid (pid, NULL, 0); + return FALSE; +} + +static void +request_data_free (RequestData *req_data) +{ + guint i; + + if (!req_data) + return; + + g_free (req_data->uuid); + g_free (req_data->id); + g_free (req_data->service_type); + + nm_clear_g_source (&req_data->watch_id); + + nm_clear_g_source (&req_data->channel_eventid); + if (req_data->channel) + g_io_channel_unref (req_data->channel); + + if (req_data->pid) { + g_spawn_close_pid (req_data->pid); + if (kill (req_data->pid, SIGTERM) == 0) + g_timeout_add_seconds (2, ensure_killed, GINT_TO_POINTER (req_data->pid)); + else { + kill (req_data->pid, SIGKILL); + /* ensure the child is reaped */ + waitpid (req_data->pid, NULL, 0); + } + } + + if (req_data->child_response) + g_string_free (req_data->child_response, TRUE); + + g_variant_builder_clear (&req_data->secrets_builder); + + if (req_data->eui_secrets) { + for (i = 0; req_data->eui_secrets[i].name; i++) { + g_free (req_data->eui_secrets[i].name); + g_free (req_data->eui_secrets[i].label); + g_free (req_data->eui_secrets[i].value); + } + g_free (req_data->eui_secrets); + } + + g_slice_free (RequestData, req_data); +} diff --git a/src/backend/dbus-interface/kylinvpnrequest.h b/src/backend/dbus-interface/kylinvpnrequest.h new file mode 100644 index 00000000..a779acd0 --- /dev/null +++ b/src/backend/dbus-interface/kylinvpnrequest.h @@ -0,0 +1,30 @@ +#ifndef KYLIN_VPN_REQUEST_H +#define KYLIN_VPN_REQUEST_H + +#include +#include "kylinagent.h" + +typedef struct _SecretsRequest SecretsRequest; +typedef void (*SecretsRequestFreeFunc) (SecretsRequest *req); +struct _SecretsRequest { + size_t totsize; + gpointer reqid; + char *setting_name; + char **hints; + guint32 flags; + AppletAgent *agent; + AppletAgentSecretsCallback callback; + gpointer callback_data; + + NMConnection *connection; + + /* Class-specific stuff */ + SecretsRequestFreeFunc free_func; +}; + + +size_t applet_vpn_request_get_secrets_size(void); + +gboolean applet_vpn_request_get_secrets(SecretsRequest *req, GError **error); + +#endif /* APPLET_VPN_REQUEST_H */ diff --git a/src/backend/dbus-interface/kylinwiredconnectoperation.cpp b/src/backend/dbus-interface/kylinwiredconnectoperation.cpp new file mode 100644 index 00000000..0f477c6f --- /dev/null +++ b/src/backend/dbus-interface/kylinwiredconnectoperation.cpp @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * 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, 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 +#include +#include +#include +#include + +KyWiredConnectOperation::KyWiredConnectOperation(QObject *parent) : KyConnectOperation(parent) +{ + +} + +KyWiredConnectOperation::~KyWiredConnectOperation() +{ +} + +void KyWiredConnectOperation::createWiredConnect(KyConnectSetting &connectSettingsInfo) +{ + qDebug()<<"[KyWiredConnectOperation]" << "create connect "; + connectSettingsInfo.dumpInfo(); + + NetworkManager::ConnectionSettings::Ptr wiredConnectionSettings = NetworkManager::ConnectionSettings::Ptr(new NetworkManager::ConnectionSettings(NetworkManager::ConnectionSettings::Wired)); + connectSettingSet(wiredConnectionSettings, connectSettingsInfo); + + NetworkManager::Ipv4Setting::Ptr ipv4Setting = wiredConnectionSettings->setting(NetworkManager::Setting::Ipv4).dynamicCast(); + ipv4SettingSet(ipv4Setting, connectSettingsInfo); + + NetworkManager::Ipv6Setting::Ptr ipv6Setting = wiredConnectionSettings->setting(NetworkManager::Setting::Ipv6).dynamicCast(); + ipv6SettingSet(ipv6Setting, connectSettingsInfo); + + NetworkManager::WiredSetting::Ptr wiredSetting = wiredConnectionSettings->setting(NetworkManager::Setting::Wired).dynamicCast(); + wiredSetting->setInitialized(true); + + QDBusPendingCallWatcher * watcher; + watcher = new QDBusPendingCallWatcher{NetworkManager::addConnection(wiredConnectionSettings->toMap()), this}; + connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher * watcher) { + if (watcher->isError() || !watcher->isValid()) { + QString errorMessage = tr("create wired connection failed: ") + watcher->error().message(); + qWarning()<createConnectionError(errorMessage); + } else { + qDebug()<<"create wired connect complete"; + } + watcher->deleteLater(); + }); + + return; +} + +void KyWiredConnectOperation::updateWiredConnect(const QString &connectUuid, const KyConnectSetting &connectSettingsInfo) +{ + qDebug()<<"update connect"<settings(); + updateConnect(connectSettingPtr, connectSettingsInfo); + + NMVariantMapMap mapmap1 = connectSettingPtr->toMap(); + if (mapmap1.contains("ipv4")) { + QVariantMap map1 = mapmap1.value(QLatin1String("ipv4")); + bool isAuto = false; + if (map1.contains("method") && map1["method"] == "auto") { + qDebug() << "[KyWiredConnectOperation] set ipv4 method auto, clear address-data && addresses && gateway"; + isAuto = true; + } + if (isAuto) { + if (map1.contains("address-data")) { + map1.remove("address-data"); + } + if (map1.contains("addresses")) { + map1.remove("addresses"); + } + if (map1.contains("gateway")) { + map1.remove("gateway"); + } + } + mapmap1["ipv4"] = map1; + } + + if (mapmap1.contains("ipv6")) { + QVariantMap map2 = mapmap1.value(QLatin1String("ipv6")); + bool isAuto = false; + if (map2.contains("method") && map2["method"] == "auto") { + qDebug() << "[KyWiredConnectOperation] set ipv6 method auto, clear address-data && addresses && gateway"; + isAuto = true; + } + if (isAuto) { + if (map2.contains("address-data")) { + map2.remove("address-data"); + } + if (map2.contains("addresses")) { + map2.remove("addresses"); + } + if (map2.contains("gateway")) { + map2.remove("gateway"); + } + } + mapmap1["ipv6"] = map2; + } + + connectPtr->update(mapmap1); + + return ; +} + +void KyWiredConnectOperation::deleteWiredConnect(const QString &connectUuid) +{ + qDebug()<<"delete wired connect uuid " << connectUuid; + + deleteConnect(connectUuid); + + return ; +} + +void KyWiredConnectOperation::activateWiredConnection(const QString connectUuid, const QString devName) +{ + activateConnection(connectUuid, devName); + return ; +} + +void KyWiredConnectOperation::deactivateWiredConnection(const QString activeConnectName, const QString &activeConnectUuid) +{ + qDebug()<<"deactivetate connect name"<settings()->connectionType()) { + QString errorMessage = tr("the connect type is") + + connectPtr->settings()->connectionType() + + tr(", but it is not vpn"); + qWarning()<path(); + connectName = connectPtr->name(); + //deviceName = connectPtr->settings()->interfaceName(); + specificObject = deviceIdentifier = QStringLiteral("/"); + + qDebug() <<"active wired connect: path "<< connectPath + << "device identify " << deviceIdentifier + << "connect name " << connectName + // << "device name" << deviceName + << "specific parameter"<< specificObject; + + QDBusPendingCallWatcher * watcher; + watcher = new QDBusPendingCallWatcher{NetworkManager::activateConnection(connectPath, deviceIdentifier, specificObject), this}; + connect(watcher, &QDBusPendingCallWatcher::finished, [this, connectName] (QDBusPendingCallWatcher * watcher) { + if (watcher->isError() || !watcher->isValid()) { + QString errorMessage = tr("activate vpn connection failed: ") + watcher->error().message(); + qWarning()<activateConnectionError(errorMessage); + } else { + qWarning()<<"active vpn connect complete."; + } + + watcher->deleteLater(); + }); + + return; +} + +void KyWiredConnectOperation::saveActiveConnection(QString &deviceName, QString &connectUuid) +{ + QSettings *p_settings = new QSettings(WIRED_NETWORK_STATE_CONF_FILE, QSettings::IniFormat); + + QString settingValue = p_settings->value(deviceName).toString(); + if (settingValue.isEmpty()) { + p_settings->setValue(deviceName, connectUuid); + p_settings->sync(); + } + + delete p_settings; + p_settings = nullptr; + + return; +} + +void KyWiredConnectOperation::getActiveConnection(QString &deviceName, QString &connectUuid) +{ + QSettings *p_settings = new QSettings(WIRED_NETWORK_STATE_CONF_FILE, QSettings::IniFormat); + + connectUuid = p_settings->value(deviceName).toString(); + p_settings->remove(deviceName); + + delete p_settings; + p_settings = nullptr; + + return; +} + +int KyWiredConnectOperation::closeWiredNetworkWithDevice(QString deviceName) +{ + NetworkManager::Device::Ptr wiredDevicePtr = + m_networkResourceInstance->findDeviceInterface(deviceName); + + if (wiredDevicePtr.isNull()) { + qWarning()<<"[KyWiredConnectOperation]"<<"the network device" << deviceName <<"is not exist."; + return -ENXIO; + } + + if (NetworkManager::Device::Type::Ethernet != wiredDevicePtr->type()) { + qWarning()<<"[KyWiredConnectOperation]"<<"the device type" + << wiredDevicePtr->type() <<"is not Ethernet."; + return -EINVAL; + } + + NetworkManager::ActiveConnection::Ptr activeConnectPtr = wiredDevicePtr->activeConnection(); + if (nullptr != activeConnectPtr) { + QString activeConnectUuid = activeConnectPtr->uuid(); + if (!activeConnectUuid.isEmpty()) { + qDebug()<<"[KyWiredConnectOperation]" <<"close wired network save connection uuid" + << activeConnectUuid <<"device name " << deviceName; + saveActiveConnection(deviceName, activeConnectUuid); + } + } + + //wiredDevicePtr->setAutoconnect(false); + wiredDevicePtr->disconnectInterface(); + + return 0; +} + +int KyWiredConnectOperation::openWiredNetworkWithDevice(QString deviceName) +{ + NetworkManager::Device::Ptr wiredDevicePtr = + m_networkResourceInstance->findDeviceInterface(deviceName); + + if (wiredDevicePtr.isNull() || !wiredDevicePtr->isValid()) { + qWarning()<<"[KyWiredConnectOperation]"<<"the network device" << deviceName <<"is not exist."; + return -ENXIO; + } + + if (NetworkManager::Device::Type::Ethernet != wiredDevicePtr->type()) { + qWarning()<<"[KyWiredConnectOperation]"<<"the device type" + << wiredDevicePtr->type() <<"is not Ethernet."; + return -EINVAL; + } + + NetworkManager::WiredDevice *p_wiredDevice = + qobject_cast(wiredDevicePtr.data()); + + if (p_wiredDevice->carrier()) { + QString connectUuid; + getActiveConnection(deviceName, connectUuid); + if (!connectUuid.isEmpty()) { + qDebug()<<"[KyWiredConnectOperation]" << "open wired network active connection" + << connectUuid <<"device name" << deviceName; + activateConnection(connectUuid, deviceName); + } + } + + wiredDevicePtr->setAutoconnect(true); + + return 0; +} diff --git a/src/backend/dbus-interface/kylinwiredconnectoperation.h b/src/backend/dbus-interface/kylinwiredconnectoperation.h new file mode 100644 index 00000000..4a0e0ee6 --- /dev/null +++ b/src/backend/dbus-interface/kylinwiredconnectoperation.h @@ -0,0 +1,36 @@ +#ifndef KYLINWIREDCONNECTOPERATION_H +#define KYLINWIREDCONNECTOPERATION_H + +#include +#include + +#include "kylinnetworkresourcemanager.h" +#include "kylinconnectsetting.h" +#include "kylinconnectoperation.h" + +const QString WIRED_NETWORK_STATE_CONF_FILE = QDir::homePath() + "/.config/ukui/kylin-nm-wired.ini"; + +class KyWiredConnectOperation : public KyConnectOperation +{ + Q_OBJECT +public: + explicit KyWiredConnectOperation(QObject *parent = nullptr); + ~KyWiredConnectOperation(); + +public: + void createWiredConnect(KyConnectSetting &connectSettingsInfo); + void updateWiredConnect(const QString &connectUuid, const KyConnectSetting &connectSettingsInfo); + void deleteWiredConnect(const QString &connectUuid); + void activateWiredConnection(const QString connectUuid, const QString devName); + void activateVpnConnection(const QString connectUuid); + void deactivateWiredConnection(const QString activeConnectName, const QString &activeConnectUuid); + + int closeWiredNetworkWithDevice(QString deviceName); + int openWiredNetworkWithDevice(QString deviceName); + +private: + void getActiveConnection(QString &deviceName, QString &connectUuid); + void saveActiveConnection(QString &deviceName, QString &connectUuid); +}; + +#endif // KYLINWIREDCONNECTOPERATION_H diff --git a/src/backend/dbus-interface/kywirelessconnectoperation.cpp b/src/backend/dbus-interface/kywirelessconnectoperation.cpp new file mode 100644 index 00000000..77394034 --- /dev/null +++ b/src/backend/dbus-interface/kywirelessconnectoperation.cpp @@ -0,0 +1,1058 @@ +#include "kywirelessconnectoperation.h" +#include "kylinutil.h" + +#include + +#define PSK_SETTING_NAME "802-11-wireless-security" +#define PRIVATE_PSK_SETTING_NAME "802-1x" + +NetworkManager::ConnectionSettings::Ptr assembleWpaXPskSettings(NetworkManager::AccessPoint::Ptr accessPoint, QString &psk, bool isAutoConnect) +{ + QByteArray rawSsid = accessPoint->rawSsid(); + QString wifiSsid = getSsidFromByteArray(rawSsid); + + NetworkManager::ConnectionSettings::Ptr settings{new NetworkManager::ConnectionSettings{NetworkManager::ConnectionSettings::Wireless}}; + settings->setId(wifiSsid); + settings->setUuid(NetworkManager::ConnectionSettings::createNewUuid()); + settings->setAutoconnect(isAutoConnect); + //Note: workaround for wrongly (randomly) initialized gateway-ping-timeout + settings->setGatewayPingTimeout(0); + + NetworkManager::WirelessSetting::Ptr wifi_sett + = settings->setting(NetworkManager::Setting::Wireless).dynamicCast(); + wifi_sett->setInitialized(true); + wifi_sett->setSsid(rawSsid); + wifi_sett->setSecurity("802-11-wireless-security"); + + NetworkManager::WirelessSecuritySetting::Ptr security_sett + = settings->setting(NetworkManager::Setting::WirelessSecurity).dynamicCast(); + security_sett->setInitialized(true); + if (NetworkManager::AccessPoint::Adhoc == accessPoint->mode()) { + wifi_sett->setMode(NetworkManager::WirelessSetting::Adhoc); + security_sett->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaNone); + } else { + security_sett->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaPsk); + } + if (!psk.isEmpty()) { + security_sett->setPsk(psk); + } + + return settings; +} + +NetworkManager::ConnectionSettings::Ptr assembleSaeSettings(NetworkManager::AccessPoint::Ptr accessPoint, QString &psk, bool isAutoConnect) +{ + QByteArray rawSsid = accessPoint->rawSsid(); + QString wifiSsid = getSsidFromByteArray(rawSsid); + + NetworkManager::ConnectionSettings::Ptr settings{new NetworkManager::ConnectionSettings{NetworkManager::ConnectionSettings::Wireless}}; + settings->setId(wifiSsid); + settings->setUuid(NetworkManager::ConnectionSettings::createNewUuid()); + settings->setAutoconnect(isAutoConnect); + //Note: workaround for wrongly (randomly) initialized gateway-ping-timeout + settings->setGatewayPingTimeout(0); + + NetworkManager::WirelessSetting::Ptr wifi_sett + = settings->setting(NetworkManager::Setting::Wireless).dynamicCast(); + wifi_sett->setInitialized(true); + wifi_sett->setSsid(rawSsid); + wifi_sett->setSecurity("802-11-wireless-security"); + + NetworkManager::WirelessSecuritySetting::Ptr security_sett + = settings->setting(NetworkManager::Setting::WirelessSecurity).dynamicCast(); + security_sett->setInitialized(true); + if (NetworkManager::AccessPoint::Adhoc == accessPoint->mode()) { + wifi_sett->setMode(NetworkManager::WirelessSetting::Adhoc); + security_sett->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaNone); + } else { + security_sett->setKeyMgmt(NetworkManager::WirelessSecuritySetting::SAE); + } + if (!psk.isEmpty()) { + security_sett->setPsk(psk); + } + + return settings; +} + +NetworkManager::ConnectionSettings::Ptr assembleWirelessSettings( + const NetworkManager::AccessPoint::Ptr accessPointPtr, + const KyWirelessConnectSetting &connSettingInfo, + bool isHidden) +{ + QByteArray rawSsid; + if (nullptr == accessPointPtr || accessPointPtr.isNull()) { + rawSsid = connSettingInfo.m_ssid.toUtf8(); + } else { + rawSsid = accessPointPtr->rawSsid(); + } + + NetworkManager::ConnectionSettings::Ptr settings{new NetworkManager::ConnectionSettings{NetworkManager::ConnectionSettings::Wireless}}; + settings->setId(connSettingInfo.m_connectName); + settings->setUuid(NetworkManager::ConnectionSettings::createNewUuid()); + settings->setAutoconnect(connSettingInfo.isAutoConnect); + //Note: workaround for wrongly (randomly) initialized gateway-ping-timeout + settings->setGatewayPingTimeout(0); + settings->setInterfaceName(connSettingInfo.m_ifaceName); + + NetworkManager::WirelessSetting::Ptr wifi_sett + = settings->setting(NetworkManager::Setting::Wireless).dynamicCast(); + wifi_sett->setInitialized(true); + wifi_sett->setSsid(rawSsid); + wifi_sett->setSecurity("802-11-wireless-security"); + wifi_sett->setHidden(isHidden); + + if (connSettingInfo.m_type != KyKeyMgmt::WpaNone && connSettingInfo.m_type != KyKeyMgmt::Unknown) + { + NetworkManager::WirelessSecuritySetting::Ptr security_sett + = settings->setting(NetworkManager::Setting::WirelessSecurity).dynamicCast(); + security_sett->setInitialized(true); + security_sett->setKeyMgmt((NetworkManager::WirelessSecuritySetting::KeyMgmt)connSettingInfo.m_type); + if (KyKeyMgmt::SAE == connSettingInfo.m_type || KyKeyMgmt::WpaPsk == connSettingInfo.m_type) + { + security_sett->setPsk(connSettingInfo.m_psk); + } + } + return settings; +} + + +KyWirelessConnectOperation::KyWirelessConnectOperation(QObject *parent) : KyConnectOperation(parent) +{ + connect(m_networkResourceInstance, &KyNetworkResourceManager::wifiEnabledChanged, + this, &KyWirelessConnectOperation::wifiEnabledChanged); + connect(this, &KyWirelessConnectOperation::enabledWirelessNetwork, + m_networkResourceInstance, &KyNetworkResourceManager::setWirelessNetworkEnabled, Qt::ConnectionType::QueuedConnection); +} + +KyWirelessConnectOperation::~KyWirelessConnectOperation() +{ + m_networkResourceInstance = nullptr; +} + +void KyWirelessConnectOperation::activeWirelessConnect(QString devIfaceName, QString connUuid) +{ + activateConnection(connUuid, devIfaceName); + return; +} + +void KyWirelessConnectOperation::deActivateWirelessConnection(const QString activeConnectName, const QString &activeConnectUuid) +{ + deactivateConnection(activeConnectName, activeConnectUuid); + return; +} + +//普通wifi +void KyWirelessConnectOperation::addConnect(const KyWirelessConnectSetting &connSettingInfo) +{ + NetworkManager::WirelessNetwork::Ptr wifiNet = + checkWifiNetExist(connSettingInfo.m_ssid, connSettingInfo.m_ifaceName); + if (wifiNet.isNull()) { + QString errorMessage = "the ssid " + connSettingInfo.m_ssid + + " is not exsit in " + connSettingInfo.m_ifaceName; + qWarning()<referenceAccessPoint(); + + NetworkManager::ConnectionSettings::Ptr connSetting = + assembleWirelessSettings(accessPointPtr, connSettingInfo, false); + setIpv4AndIpv6Setting(connSetting, connSettingInfo); + + QDBusPendingCallWatcher * watcher; + watcher = new QDBusPendingCallWatcher{NetworkManager::addConnection(connSetting->toMap()), this}; + connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher * watcher) { + if (watcher->isError() || !watcher->isValid()) { + QString errorMessage = tr("create wireless connection failed: ") + watcher->error().message(); + qWarning()<createConnectionError(errorMessage); + } else { + qDebug()<<"create wireless connect complete"; + } + watcher->deleteLater(); + }); + + return; +} +//tls +void KyWirelessConnectOperation::addTlsConnect(const KyWirelessConnectSetting &connSettingInfo, const KyEapMethodTlsInfo &tlsInfo) +{ + NetworkManager::WirelessNetwork::Ptr wifiNet = + checkWifiNetExist(connSettingInfo.m_ssid, connSettingInfo.m_ifaceName); + if (wifiNet.isNull()) { + QString errorMessage = "the ssid " + connSettingInfo.m_ssid + + " is not exsit in " + connSettingInfo.m_ifaceName; + qWarning()<referenceAccessPoint(); + NetworkManager::ConnectionSettings::Ptr connSetting = + assembleWirelessSettings(accessPointPtr, connSettingInfo, false); + setIpv4AndIpv6Setting(connSetting, connSettingInfo); + assembleEapMethodTlsSettings(connSetting, tlsInfo); + + QDBusPendingCallWatcher * watcher; + watcher = new QDBusPendingCallWatcher{NetworkManager::addConnection(connSetting->toMap()), this}; + connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher * watcher) { + if (watcher->isError() || !watcher->isValid()) { + QString errorMessage = tr("create wireless tls connection failed: ") + watcher->error().message(); + qWarning()<createConnectionError(errorMessage); + } else { + qDebug()<<"create wireless connect complete"; + } + watcher->deleteLater(); + }); + + return; +} +//peap +void KyWirelessConnectOperation::addPeapConnect(const KyWirelessConnectSetting &connSettingInfo, const KyEapMethodPeapInfo &peapInfo) +{ + NetworkManager::WirelessNetwork::Ptr wifiNet = + checkWifiNetExist(connSettingInfo.m_ssid, connSettingInfo.m_ifaceName); + if (wifiNet.isNull()) { + QString errorMessage = "the ssid " + connSettingInfo.m_ssid + + " is not exsit in " + connSettingInfo.m_ifaceName; + qWarning()<referenceAccessPoint(); + NetworkManager::ConnectionSettings::Ptr connSetting = + assembleWirelessSettings(accessPointPtr, connSettingInfo, false); + setIpv4AndIpv6Setting(connSetting, connSettingInfo); + assembleEapMethodPeapSettings(connSetting, peapInfo); + + QDBusPendingCallWatcher * watcher; + watcher = new QDBusPendingCallWatcher{NetworkManager::addConnection(connSetting->toMap()), this}; + connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher * watcher) { + if (watcher->isError() || !watcher->isValid()) { + QString errorMessage = tr("create wireless peap connection failed: ") + watcher->error().message(); + qWarning()<createConnectionError(errorMessage); + } else { + qDebug()<<"create wireless connect complete"; + } + watcher->deleteLater(); + }); + + return; +} + +void KyWirelessConnectOperation::addTtlsConnect(const KyWirelessConnectSetting &connSettingInfo, const KyEapMethodTtlsInfo &ttlsInfo) +{ + NetworkManager::WirelessNetwork::Ptr wifiNet = + checkWifiNetExist(connSettingInfo.m_ssid, connSettingInfo.m_ifaceName); + if (wifiNet.isNull()) { + QString errorMessage = "the ssid " + connSettingInfo.m_ssid + + " is not exsit in " + connSettingInfo.m_ifaceName; + qWarning()<referenceAccessPoint(); + NetworkManager::ConnectionSettings::Ptr connSetting = + assembleWirelessSettings(accessPointPtr, connSettingInfo, false); + setIpv4AndIpv6Setting(connSetting, connSettingInfo); + assembleEapMethodTtlsSettings(connSetting, ttlsInfo); + + QDBusPendingCallWatcher * watcher; + watcher = new QDBusPendingCallWatcher{NetworkManager::addConnection(connSetting->toMap()), this}; + connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher * watcher) { + if (watcher->isError() || !watcher->isValid()) { + QString errorMessage = tr("create wireless ttls connection failed: ") + watcher->error().message(); + qWarning()<createConnectionError(errorMessage); + } else { + qDebug()<<"create wireless connect complete"; + } + watcher->deleteLater(); + }); + + return; +} + +void KyWirelessConnectOperation::setWirelessAutoConnect(const QString &uuid, bool bAutoConnect) +{ + NetworkManager::Connection::Ptr connectPtr = + NetworkManager::findConnectionByUuid(uuid); + if (nullptr == connectPtr) { + QString errorMessage = tr("it can not find connection") + uuid; + qWarning()<settings(); + setAutoConnect(connectionSettings, bAutoConnect); + connectPtr->update(connectionSettings->toMap()); + return; +} + +void KyWirelessConnectOperation::deleteWirelessConnect(const QString &connectUuid) +{ + qDebug()<<"delete wireless connect uuid " << connectUuid; + + deleteConnect(connectUuid); + + return ; +} + +QString KyWirelessConnectOperation::getPsk(const QString &connectUuid) +{ + qDebug() << "getPsk" << connectUuid; + NetworkManager::Connection::Ptr connectPtr = + NetworkManager::findConnectionByUuid(connectUuid); + if (connectPtr.isNull()) { + QString errorMessage = tr("it can not find connection") + connectUuid; + qWarning()< reply = connectPtr->secrets(PSK_SETTING_NAME); + QMap map(reply.value()); + if (map.contains("802-11-wireless-security") + && map.value("802-11-wireless-security").contains("psk")) { + QString psk = map.value("802-11-wireless-security").value("psk").toString(); + return psk; + } + return ""; +} + +QString KyWirelessConnectOperation::getPrivateKeyPassword(const QString &connectUuid) +{ + qDebug() << "getPsk" << connectUuid; + NetworkManager::Connection::Ptr connectPtr = + NetworkManager::findConnectionByUuid(connectUuid); + if (connectPtr.isNull()) { + QString errorMessage = tr("it can not find connection") + connectUuid; + qWarning()< reply = connectPtr->secrets(PRIVATE_PSK_SETTING_NAME); + QMap map(reply.value()); + if (map.contains("802-1x") + && map.value("802-1x").contains("private-key-password")) { + QString psk = map.value("802-1x").value("private-key-password").toString(); + return psk; + } + return ""; +} + +QString KyWirelessConnectOperation::get8021xPassword(const QString &connectUuid) +{ + qDebug() << "getPsk" << connectUuid; + NetworkManager::Connection::Ptr connectPtr = + NetworkManager::findConnectionByUuid(connectUuid); + if (connectPtr.isNull()) { + QString errorMessage = tr("it can not find connection") + connectUuid; + qWarning()< reply = connectPtr->secrets(PRIVATE_PSK_SETTING_NAME); + QMap map(reply.value()); + if (map.contains("802-1x") && map.value("802-1x").contains("password")) + { + QString psk = map.value("802-1x").value("password").toString(); + return psk; + } + return ""; +} + +void KyWirelessConnectOperation::updateIpv4AndIpv6SettingInfo(const QString &uuid, const KyConnectSetting &connectSettingsInfo) +{ + qDebug()<<"updateIpv4AndIpv6SettingInfo wireless connect uuid " << uuid; + + NetworkManager::Connection::Ptr connectPtr = + NetworkManager::findConnectionByUuid(uuid); + if (nullptr == connectPtr) { + QString errorMessage = tr("it can not find connection") + uuid; + qWarning()<settings(); + + setIpv4AndIpv6Setting(connectionSettings,connectSettingsInfo); + connectPtr->update(connectionSettings->toMap()); + return; +} + +void KyWirelessConnectOperation::updateWirelessPersonalConnect(const QString &uuid, const KyWirelessConnectSetting &connSettingInfo, bool bPwdChange) +{ + NetworkManager::Connection::Ptr connectPtr = + NetworkManager::findConnectionByUuid(uuid); + if (nullptr == connectPtr) { + QString errorMessage = tr("it can not find connection") + uuid; + qWarning()<settings(); + + if (connSettingInfo.m_type != Unknown &&connSettingInfo.m_type != WpaNone && connSettingInfo.m_type != WpaPsk && connSettingInfo.m_type != SAE) + { + qDebug() << "updateWirelessPersonalConnect " << connSettingInfo.m_type << " not support"; + return; + } + + NetworkManager::Security8021xSetting::Ptr wifi_8021x_sett + = connectionSettings->setting(NetworkManager::Setting::Security8021x).dynamicCast(); + wifi_8021x_sett->setInitialized(false); + + updateWirelessSecu(connectionSettings, connSettingInfo, bPwdChange); + connectPtr->update(connectionSettings->toMap()); + return; +} + +void KyWirelessConnectOperation::updateWirelessEnterPriseTlsConnect(const QString &uuid, const KyEapMethodTlsInfo &tlsInfo) +{ + NetworkManager::Connection::Ptr connectPtr = + NetworkManager::findConnectionByUuid(uuid); + if (connectPtr.isNull()) { + QString errorMessage = tr("it can not find connection") + uuid; + qWarning()<settings(); + + setWirelessSecuWpaXEap(connectionSettings); + modifyEapMethodTlsSettings(connectionSettings, tlsInfo); + connectPtr->update(connectionSettings->toMap()); + return; +} + +void KyWirelessConnectOperation::updateWirelessEnterPrisePeapConnect(const QString &uuid, const KyEapMethodPeapInfo &peapInfo) +{ + NetworkManager::Connection::Ptr connectPtr = + NetworkManager::findConnectionByUuid(uuid); + if (nullptr == connectPtr) { + QString errorMessage = tr("it can not find connection") + uuid; + qWarning()<settings(); + + setWirelessSecuWpaXEap(connectionSettings); + modifyEapMethodPeapSettings(connectionSettings, peapInfo); + connectPtr->update(connectionSettings->toMap()); + return; +} + +void KyWirelessConnectOperation::updateWirelessEnterPriseTtlsConnect(const QString &uuid, const KyEapMethodTtlsInfo &ttlsInfo) +{ + NetworkManager::Connection::Ptr connectPtr = + NetworkManager::findConnectionByUuid(uuid); + if (nullptr == connectPtr) { + QString errorMessage = tr("it can not find connection") + uuid; + qWarning()<settings(); + + setWirelessSecuWpaXEap(connectionSettings); + modifyEapMethodTtlsSettings(connectionSettings, ttlsInfo); + connectPtr->update(connectionSettings->toMap()); + return; +} + +void KyWirelessConnectOperation::addAndActiveWirelessConnect(QString & devIface,KyWirelessConnectSetting &connSettingInfo,bool isHidden) +{ + qDebug() << "addAndActiveWirelessConnect" << connSettingInfo.m_ssid << devIface <findDeviceInterface(devIface); + if (dev.isNull()) { + emit addAndActivateConnectionError("can not find device"); + return; + } + + qDebug() << "addAndActiveWirelessConnect device " << devIface << " exist"; + dev_uni = dev->uni(); + auto spec_dev = dev->as(); + if (!isHidden) { + qDebug() << "start assemble"; + auto access_point = wifiNet->referenceAccessPoint(); + conn_uni = access_point->uni(); + conn_name = access_point->ssid(); + spec_object = conn_uni; + + NetworkManager::WirelessSecurityType sec_type = NetworkManager::findBestWirelessSecurity(spec_dev->wirelessCapabilities() + , true, (spec_dev->mode() == NetworkManager::WirelessDevice::Adhoc) + , access_point->capabilities(), access_point->wpaFlags(), access_point->rsnFlags()); + + qDebug() << "findBestWirelessSecurity type "<< sec_type; + + NetworkManager::ConnectionSettings::Ptr settings = nullptr; + switch (sec_type) + { + case NetworkManager::UnknownSecurity: + qWarning() << QStringLiteral("unknown security to use for '%1'").arg(conn_name); + case NetworkManager::NoneSecurity: + //nothing to do + break; + case NetworkManager::WpaPsk: + case NetworkManager::Wpa2Psk: + settings = assembleWpaXPskSettings(access_point, connSettingInfo.m_psk, connSettingInfo.isAutoConnect); + if (nullptr != settings) { + map_settings = settings->toMap(); + } else { + qWarning() << QStringLiteral("connection settings assembly for '%1' failed, abandoning activation...").arg(conn_name); + return; + } + break; + //TODO: other types... + case NetworkManager::SAE: + settings = assembleSaeSettings(access_point, connSettingInfo.m_psk, connSettingInfo.isAutoConnect); + if (nullptr != settings) { + map_settings = settings->toMap(); + } else { + qWarning() << QStringLiteral("connection settings assembly for '%1' failed, abandoning activation...").arg(conn_name); + return; + } + break; + default: + qDebug() << "addAndActiveWirelessConnect not support"; + break; + } + + qDebug() << "finish assemble"; + } else { + qDebug() << "start assembleWirelessSettings"; + map_settings = assembleWirelessSettings(nullptr, connSettingInfo, isHidden)->toMap(); + qDebug() << "finish assembleWirelessSettings"; + } + + QDBusPendingCallWatcher * watcher; + watcher = new QDBusPendingCallWatcher{NetworkManager::addAndActivateConnection(map_settings, dev_uni, spec_object), this}; + connect(watcher, &QDBusPendingCallWatcher::finished, [&] (QDBusPendingCallWatcher * watcher) { + if (watcher->isError() || !watcher->isValid()) { + QString errorMessage = watcher->error().message(); + qDebug() << "activation of connection failed " << errorMessage; + emit addAndActivateConnectionError(errorMessage); + } + watcher->deleteLater(); + }); +} + +void KyWirelessConnectOperation::requestWirelessScan() +{ + for (auto const & dev : m_networkResourceInstance->m_devices) { + auto spec_dev = dev->as(); + if (nullptr != spec_dev) { + m_networkResourceInstance->requestScan(spec_dev); + } + } +} + +void KyWirelessConnectOperation::addAndActiveWirelessEnterPriseTlsConnect(KyEapMethodTlsInfo &info, KyWirelessConnectSetting &connSettingInfo, + QString & devIface, bool isHidden) +{ + QString conn_uni; + QString dev_uni; + QString spec_object; + NMVariantMapMap map_settings; + NetworkManager::AccessPoint::Ptr accessPointPtr = nullptr; + + if (!isHidden) { + NetworkManager::WirelessNetwork::Ptr wifiNet = checkWifiNetExist(connSettingInfo.m_ssid, devIface); + if (wifiNet.isNull()) { + QString errorMessage = "the ssid " + connSettingInfo.m_ssid + " is not exsit in " + devIface; + qWarning()<referenceAccessPoint(); + conn_uni = accessPointPtr->uni(); + spec_object = conn_uni; + } + + auto dev = m_networkResourceInstance->findDeviceInterface(devIface); + if (dev.isNull()) { + emit addAndActivateConnectionError("can not find device"); + return; + } + dev_uni = dev->uni(); + + NetworkManager::ConnectionSettings::Ptr settings = assembleWirelessSettings(accessPointPtr, connSettingInfo, isHidden); + assembleEapMethodTlsSettings(settings, info); + + if(settings.isNull()) { + qDebug() << "assembleEapMethodTlsSettings failed"; + return; + } + + map_settings = settings->toMap(); + + QDBusPendingCallWatcher * watcher; + watcher = new QDBusPendingCallWatcher{NetworkManager::addAndActivateConnection(map_settings, dev_uni, spec_object), this}; + connect(watcher, &QDBusPendingCallWatcher::finished, [&] (QDBusPendingCallWatcher * watcher) { + if (watcher->isError() || !watcher->isValid()) { + QString errorMessage = watcher->error().message(); + qDebug() << "addAndActiveWirelessEnterPriseTlsConnect failed " << errorMessage; + emit addAndActivateConnectionError(errorMessage); + } + watcher->deleteLater(); + }); + +} + +void KyWirelessConnectOperation::addAndActiveWirelessEnterPrisePeapConnect(KyEapMethodPeapInfo &info, KyWirelessConnectSetting &connSettingInfo, + QString & devIface, bool isHidden) +{ + qDebug() <<"addAndActiveWirelessEnterPrisePeapConnect"; + QString conn_uni; + QString dev_uni; + QString spec_object; + NMVariantMapMap map_settings; + NetworkManager::AccessPoint::Ptr accessPointPtr = nullptr; + + if (!isHidden) { + NetworkManager::WirelessNetwork::Ptr wifiNet = checkWifiNetExist(connSettingInfo.m_ssid, devIface); + if (wifiNet.isNull()) { + QString errorMessage = "the ssid " + connSettingInfo.m_ssid + " is not exsit in " + devIface; + qWarning()<referenceAccessPoint(); + conn_uni = accessPointPtr->uni(); + spec_object = conn_uni; + } + + auto dev = m_networkResourceInstance->findDeviceInterface(devIface); + if (dev.isNull()) { + emit addAndActivateConnectionError("can not find device"); + return; + } + dev_uni = dev->uni(); + + NetworkManager::ConnectionSettings::Ptr settings = + assembleWirelessSettings(accessPointPtr, connSettingInfo, isHidden); + assembleEapMethodPeapSettings(settings, info); + + if(settings.isNull()) { + qDebug() << "assembleEapMethodPeapSettings failed"; + return; + } + map_settings = settings->toMap(); + + QDBusPendingCallWatcher * watcher; + watcher = new QDBusPendingCallWatcher{NetworkManager::addAndActivateConnection(map_settings, dev_uni, spec_object), this}; + connect(watcher, &QDBusPendingCallWatcher::finished, [&] (QDBusPendingCallWatcher * watcher) { + if (watcher->isError() || !watcher->isValid()) { + QString errorMessage = watcher->error().message(); + qDebug() << "addAndActiveWirelessEnterPrisePeapConnect failed " << errorMessage; + emit addAndActivateConnectionError(errorMessage); + } + watcher->deleteLater(); + }); + +} + +void KyWirelessConnectOperation::addAndActiveWirelessEnterPriseTtlsConnect(KyEapMethodTtlsInfo &info, KyWirelessConnectSetting &connSettingInfo, + QString & devIface, bool isHidden) +{ + QString conn_uni; + QString dev_uni; + QString spec_object; + NMVariantMapMap map_settings; + NetworkManager::AccessPoint::Ptr accessPointPtr = nullptr; + + if (!isHidden) { + NetworkManager::WirelessNetwork::Ptr wifiNet = checkWifiNetExist(connSettingInfo.m_ssid, devIface); + if (wifiNet.isNull()) { + QString errorMessage = "the ssid " + connSettingInfo.m_ssid + " is not exsit in " + devIface; + qWarning()<referenceAccessPoint(); + conn_uni = accessPointPtr->uni(); + spec_object = conn_uni; + } + + auto dev = m_networkResourceInstance->findDeviceInterface(devIface); + if (dev.isNull()) { + emit addAndActivateConnectionError("can not find device"); + return; + } + dev_uni = dev->uni(); + + NetworkManager::ConnectionSettings::Ptr settings = + assembleWirelessSettings(accessPointPtr, connSettingInfo, isHidden); + assembleEapMethodTtlsSettings(settings, info); + + if(settings.isNull()) { + qDebug() << "assembleEapMethodTtlsSettings failed"; + return; + } + + map_settings = settings->toMap(); + + QDBusPendingCallWatcher * watcher; + watcher = new QDBusPendingCallWatcher{NetworkManager::addAndActivateConnection(map_settings, dev_uni, spec_object), this}; + connect(watcher, &QDBusPendingCallWatcher::finished, [&] (QDBusPendingCallWatcher * watcher) { + if (watcher->isError() || !watcher->isValid()) { + QString errorMessage = watcher->error().message(); + qDebug() << "addAndActiveWirelessEnterPriseTtlsConnect failed " << errorMessage; + emit addAndActivateConnectionError(errorMessage); + } + watcher->deleteLater(); + }); +} + +//无线网络开关设置 +void KyWirelessConnectOperation::setWirelessEnabled(bool enabled) +{ + emit enabledWirelessNetwork(enabled); + + return; +} + +bool KyWirelessConnectOperation::getWirelessEnabled() +{ + return NetworkManager::isWirelessEnabled(); +} + +bool KyWirelessConnectOperation::getConnSecretFlags(QString &connUuid, NetworkManager::Setting::SecretFlags &flag) +{ + NetworkManager::Connection::Ptr conn; + conn = m_networkResourceInstance->getConnect(connUuid); + if (conn.isNull()) { + qDebug() <<"get failed"; + return false; + } + + NetworkManager::WirelessSecuritySetting::Ptr security_sett + = conn->settings()->setting(NetworkManager::Setting::WirelessSecurity).dynamicCast(); + flag = security_sett->pskFlags(); + return true; +} + +NetworkManager::ConnectionSettings::Ptr + KyWirelessConnectOperation::createWirelessApSetting(const QString apSsid, + const QString apPassword, + const QString apDevice, + const QString wirelessBand) +{ + NetworkManager::ConnectionSettings::Ptr connectionSettings = + NetworkManager::ConnectionSettings::Ptr(new NetworkManager::ConnectionSettings(NetworkManager::ConnectionSettings::Wireless)); + connectionSettings->setId(apSsid); + connectionSettings->setUuid(NetworkManager::ConnectionSettings::createNewUuid()); + connectionSettings->setAutoconnect(false); + connectionSettings->setAutoconnectPriority(0); + connectionSettings->setInterfaceName(apDevice); + //Note: workaround for wrongly (randomly) initialized gateway-ping-timeout + connectionSettings->setGatewayPingTimeout(0); + + NetworkManager::Ipv4Setting::Ptr ipv4Setting = connectionSettings->setting(NetworkManager::Setting::Ipv4).dynamicCast(); + ipv4Setting->setInitialized(true); + ipv4Setting->setMethod(NetworkManager::Ipv4Setting::Shared); + + NetworkManager::Ipv6Setting::Ptr ipv6Setting = connectionSettings->setting(NetworkManager::Setting::Ipv6).dynamicCast(); + ipv6Setting->setInitialized(true); + ipv6Setting->setMethod(NetworkManager::Ipv6Setting::Ignored); + + NetworkManager::WirelessSetting::Ptr wirelessSetting + = connectionSettings->setting(NetworkManager::Setting::Wireless).dynamicCast(); + wirelessSetting->setInitialized(true); + wirelessSetting->setSsid(apSsid.toUtf8()); + wirelessSetting->setMode(NetworkManager::WirelessSetting::NetworkMode::Ap); + wirelessSetting->setSecurity("802-11-wireless-security"); + if (wirelessBand == WIFI_BAND_2_4GHZ) { + wirelessSetting->setBand(NetworkManager::WirelessSetting::FrequencyBand::Bg); + } else if (wirelessBand == WIFI_BAND_5GHZ) { + wirelessSetting->setBand(NetworkManager::WirelessSetting::FrequencyBand::A); + } else { + qWarning()<<"[KyWirelessConnectOperation] the band type undefined"<setBand(NetworkManager::WirelessSetting::FrequencyBand::Automatic); + } + + + NetworkManager::WirelessSecuritySetting::Ptr wirelessSecuritySetting + = connectionSettings->setting(NetworkManager::Setting::WirelessSecurity).dynamicCast(); + if (apPassword.isEmpty()) { + wirelessSecuritySetting->setInitialized(false); + } else { + wirelessSecuritySetting->setInitialized(true); + wirelessSecuritySetting->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaPsk); + wirelessSecuritySetting->setPsk(apPassword); + } + + return connectionSettings; +} + +void KyWirelessConnectOperation::updateWirelessApSetting( + NetworkManager::Connection::Ptr apConnectPtr, + const QString apName, const QString apPassword, + const QString apDevice, const QString wirelessBand) + +{ + NetworkManager::ConnectionSettings::Ptr apConnectSettingPtr = apConnectPtr->settings(); + apConnectSettingPtr->setId(apName); + apConnectSettingPtr->setInterfaceName(apDevice); + apConnectSettingPtr->setAutoconnect(false); + + NetworkManager::WirelessSetting::Ptr wirelessSetting + = apConnectSettingPtr->setting(NetworkManager::Setting::Wireless).dynamicCast(); + wirelessSetting->setInitialized(true); + wirelessSetting->setSsid(apName.toUtf8()); + if (wirelessBand == WIFI_BAND_2_4GHZ) { + wirelessSetting->setBand(NetworkManager::WirelessSetting::FrequencyBand::Bg); + } else if (wirelessBand == WIFI_BAND_5GHZ) { + wirelessSetting->setBand(NetworkManager::WirelessSetting::FrequencyBand::A); + } else { + qWarning()<<"[KyWirelessConnectOperation] the band type undefined"<setBand(NetworkManager::WirelessSetting::FrequencyBand::Automatic); + } + + + NetworkManager::WirelessSecuritySetting::Ptr wirelessSecuritySetting + = apConnectSettingPtr->setting(NetworkManager::Setting::WirelessSecurity).dynamicCast(); + if (apPassword.isEmpty()) { + wirelessSecuritySetting->setInitialized(false); + } else { + wirelessSecuritySetting->setInitialized(true); + wirelessSecuritySetting->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaPsk); + wirelessSecuritySetting->setPsk(apPassword); + } + + apConnectPtr->update(apConnectSettingPtr->toMap()); +} + +void KyWirelessConnectOperation::activeWirelessAp(const QString apUuid, const QString apName, + const QString apPassword, const QString apDevice, + const QString wirelessBand) + +{ + qDebug() << "activeWirelessAp]" << apUuid << apName << apPassword << apDevice << wirelessBand; + //1、检查连接是否存在 + NetworkManager::Connection::Ptr connectPtr = m_networkResourceInstance->getConnect(apUuid); + if (nullptr == connectPtr) { + NetworkManager::Device::Ptr devicePtr = m_networkResourceInstance->findDeviceInterface(apDevice); + if (devicePtr.isNull()) { + QString errorMsg ="Create hotspot faild. " + apDevice + " is not existed"; + qWarning()<< errorMsg; + emit addAndActivateConnectionError(errorMsg); + return; + } + + QString deviceIdentifier = devicePtr->uni(); + + NetworkManager::ConnectionSettings::Ptr apConnectSettingPtr = + createWirelessApSetting(apName, apPassword, apDevice, wirelessBand); + QString specificObject = ""; + QDBusPendingCallWatcher * watcher; + watcher = new QDBusPendingCallWatcher{NetworkManager::addAndActivateConnection(apConnectSettingPtr->toMap(), deviceIdentifier, specificObject), this}; + connect(watcher, &QDBusPendingCallWatcher::finished, [&] (QDBusPendingCallWatcher * watcher) { + if (watcher->isError() || !watcher->isValid()) { + QString errorMsg = "Create hotspot faild. " + watcher->error().message(); + qWarning() << errorMsg; + emit addAndActivateConnectionError(errorMsg); + } + watcher->deleteLater(); + }); + } else { + updateWirelessApSetting(connectPtr, apName, apPassword, apDevice, wirelessBand); + QTimer::singleShot(500, this, [=](){ + activateApConnectionByUuid(apUuid, apDevice); + }); + } + + return; +} + +void KyWirelessConnectOperation::deactiveWirelessAp(const QString apName, const QString apUuid) +{ + deactivateConnection(apName, apUuid); + return; +} + +//private +NetworkManager::WirelessNetwork::Ptr KyWirelessConnectOperation::checkWifiNetExist(QString ssid, QString devName) +{ + for (auto const & net : m_networkResourceInstance->m_wifiNets) { + auto dev = m_networkResourceInstance->findDeviceUni(net->device()); + if (dev == nullptr) { + continue; + } + if (dev->type() != NetworkManager::Device::Wifi || dev->interfaceName() != devName) { + continue; + } + + NetworkManager::AccessPoint::Ptr accessPointPtr = net->referenceAccessPoint(); + QByteArray rawSsid = accessPointPtr->rawSsid(); + QString wifiSsid = getSsidFromByteArray(rawSsid); + + if (ssid == wifiSsid) { + return net; + } + } + return nullptr; +} + +KyKeyMgmt KyWirelessConnectOperation::getConnectKeyMgmt(const QString &uuid) +{ + NetworkManager::Connection::Ptr connectPtr = + NetworkManager::findConnectionByUuid(uuid); + if (connectPtr.isNull()) { + return KyKeyMgmt::Unknown; + } + + NetworkManager::WirelessSecuritySetting::Ptr security_sett + = connectPtr->settings()->setting(NetworkManager::Setting::WirelessSecurity).dynamicCast(); + + if(security_sett.isNull()) { + return KyKeyMgmt::Unknown; + } + return (KyKeyMgmt)security_sett->keyMgmt(); +} + +void KyWirelessConnectOperation::updateWirelessSecu(NetworkManager::ConnectionSettings::Ptr connSettingPtr, const KyWirelessConnectSetting &connSettingInfo, bool bPwdChange) +{ + qDebug() << "updateWirelessSecu " << connSettingInfo.m_type; + NetworkManager::WirelessSecuritySetting::Ptr security_sett + = connSettingPtr->setting(NetworkManager::Setting::WirelessSecurity).dynamicCast(); + + KyKeyMgmt type = connSettingInfo.m_type; + qDebug() << "set keyMgmt " << type; + if (type == WpaNone) { + security_sett->setInitialized(false); + return; + } else { + security_sett->setInitialized(true); + } + security_sett->setKeyMgmt((NetworkManager::WirelessSecuritySetting::KeyMgmt)type); + if (bPwdChange) { + security_sett->setPsk(connSettingInfo.m_psk); + NetworkManager::Setting::SecretFlags flag = NetworkManager::Setting::None; + security_sett->setPskFlags(flag); + } + return; +} + +void KyWirelessConnectOperation::setWirelessSecuWpaXEap(NetworkManager::ConnectionSettings::Ptr connSettingPtr) +{ + NetworkManager::WirelessSecuritySetting::Ptr security_sett + = connSettingPtr->setting(NetworkManager::Setting::WirelessSecurity).dynamicCast(); + + security_sett->setInitialized(true); + security_sett->setKeyMgmt(NetworkManager::WirelessSecuritySetting::KeyMgmt::WpaEap); + return; +} + +void KyWirelessConnectOperation::setIpv4AndIpv6Setting(NetworkManager::ConnectionSettings::Ptr connSetting, const KyConnectSetting &connSettingInfo) +{ + NetworkManager::Ipv4Setting::Ptr ipv4Setting = connSetting->setting(NetworkManager::Setting::Ipv4).dynamicCast(); + ipv4SettingSet(ipv4Setting, connSettingInfo); + + NetworkManager::Ipv6Setting::Ptr ipv6Setting = connSetting->setting(NetworkManager::Setting::Ipv6).dynamicCast(); + ipv6SettingSet(ipv6Setting, connSettingInfo); +} + +void KyWirelessConnectOperation::activateApConnectionByUuid(const QString apUuid, const QString apDevice) +{ + QString connectPath = ""; + QString deviceIdentifier = ""; + QString connectName = ""; + QString specificObject = ""; + + qDebug()<<"it will activate hotspot connect"<getConnect(apUuid); + if (connectPtr.isNull()) + { + QString errorMessage = tr("Create hotspot faild.UUID is empty, its name") + apUuid; + qWarning() << errorMessage; + Q_EMIT activateConnectionError(errorMessage); + return; + } + connectPath = connectPtr->path(); + connectName = connectPtr->name(); + + auto dev = m_networkResourceInstance->findDeviceInterface(apDevice); + if (!dev.isNull()) { + deviceIdentifier = dev->uni(); + } + + if (deviceIdentifier.isEmpty()) { + QString errorMessage = tr("Create hotspot faild.Device Identifier is empty, its name") + apDevice; + qWarning() << errorMessage; + Q_EMIT activateConnectionError(errorMessage); + return ; + } + + QDBusPendingCallWatcher * watcher; + watcher = new QDBusPendingCallWatcher{NetworkManager::activateConnection(connectPath, deviceIdentifier, specificObject), this}; + connect(watcher, &QDBusPendingCallWatcher::finished, [this, connectName, apDevice] (QDBusPendingCallWatcher * watcher) { + if (watcher->isError() || !watcher->isValid()) { + QString errorMessage = tr("Create hotspot faild. ") + watcher->error().message(); + qWarning()<activateConnectionError(errorMessage); + } else { + qWarning()<<"active wired connect complete."; + } + + watcher->deleteLater(); + }); + + return ; +} + +bool KyWirelessConnectOperation::getEnterpiseEapMethod(const QString &uuid, KyEapMethodType &type) +{ + NetworkManager::Connection::Ptr connectPtr = + NetworkManager::findConnectionByUuid(uuid); + if (connectPtr.isNull()) { + qWarning() << "getEnterpiseEapMethod faild.Can't find uuid = " << uuid; + return false; + } + + KyKeyMgmt keyMgmt = getConnectKeyMgmt(uuid); + if (keyMgmt != WpaEap) { + qWarning() << "getEnterpiseEapMethod but not WpaEap.it's " << keyMgmt; + return false; + } + + NetworkManager::ConnectionSettings::Ptr connectionSettings = connectPtr->settings(); + + NetworkManager::Security8021xSetting::Ptr wifi_8021x_sett + = connectionSettings->setting(NetworkManager::Setting::Security8021x).dynamicCast(); + + QList list = wifi_8021x_sett->eapMethods(); + + if (list.contains(NetworkManager::Security8021xSetting::EapMethod::EapMethodTls)) { + type = TLS; + } else if (list.contains(NetworkManager::Security8021xSetting::EapMethod::EapMethodPeap)) { + type = PEAP; + } else if (list.contains(NetworkManager::Security8021xSetting::EapMethod::EapMethodTtls)) { + type = TTLS; + } + + return true; +} diff --git a/src/backend/dbus-interface/kywirelessconnectoperation.h b/src/backend/dbus-interface/kywirelessconnectoperation.h new file mode 100644 index 00000000..89618905 --- /dev/null +++ b/src/backend/dbus-interface/kywirelessconnectoperation.h @@ -0,0 +1,140 @@ +#ifndef KYWIRELESSCONNECTOPERATION_H +#define KYWIRELESSCONNECTOPERATION_H + +#include +#include +#include +#include "kyenterpricesettinginfo.h" +#include "kylinconnectoperation.h" +#include "kyenterpricesettinginfo.h" + +const QByteArray GSETTINGS_SCHEMA = "org.ukui.kylin-nm.switch"; +const QString WIRELESS_SWITCH = "wirelessswitch"; + +const QString WIFI_BAND_2_4GHZ = "2.4Ghz"; +const QString WIFI_BAND_5GHZ = "5Ghz"; + +enum KySecuType { + NONE = 0, + WPA_AND_WPA2_PERSONAL, + WPA_AND_WPA2_ENTERPRISE, + WPA3_PERSONAL, +}; + +enum KyKeyMgmt { + Unknown = -1, + Wep, Ieee8021x, + WpaNone, + WpaPsk, + WpaEap, + SAE +}; + +class KyWirelessConnectSetting : public KyConnectSetting +{ +// Q_OBJECT + +public: + QString m_ssid; + bool isAutoConnect; + QString m_psk; + NetworkManager::Setting::SecretFlags m_secretFlag; + KyKeyMgmt m_type; + //only if m_type == WpaEap + KyEapMethodType m_eapMethodType; +}; + + +class KyWirelessConnectOperation : public KyConnectOperation +{ + Q_OBJECT +public: + explicit KyWirelessConnectOperation(QObject *parent = nullptr); + ~KyWirelessConnectOperation(); + + //无线开关 + void setWirelessEnabled(bool enabled); + bool getWirelessEnabled(); + + //获取密码保存策略 + bool getConnSecretFlags(QString &connUuid, NetworkManager::Setting::SecretFlags &); + + //获取KeyMgmt + KyKeyMgmt getConnectKeyMgmt(const QString &uuid); + + //获取企业网类型 + bool getEnterpiseEapMethod(const QString &uuid, KyEapMethodType &type); + + //激活连接 + void activeWirelessConnect(QString , QString); + //断开连接 + void deActivateWirelessConnection(const QString activeConnectName, const QString &activeConnectUuid); + //新增普通连接 + void addConnect(const KyWirelessConnectSetting &connSettingInfo); + //新增TLS连接 + void addTlsConnect(const KyWirelessConnectSetting &connSettingInfo, const KyEapMethodTlsInfo &tlsinfo); + //新增PEAP连接 + void addPeapConnect(const KyWirelessConnectSetting &connSettingInfo, const KyEapMethodPeapInfo &peapInfo); + //新增TTLS连接 + void addTtlsConnect(const KyWirelessConnectSetting &connSettingInfo, const KyEapMethodTtlsInfo &ttlsInfo); + //新增连接并激活(普通wifi) + void addAndActiveWirelessConnect(QString & devIface,KyWirelessConnectSetting &connSettingInfo,bool isHidden); + + //新增连接并激活(企业wifi) + void addAndActiveWirelessEnterPriseTlsConnect(KyEapMethodTlsInfo &info, KyWirelessConnectSetting &connSettingInfo, + QString & devIface, bool isHidden); + void addAndActiveWirelessEnterPrisePeapConnect(KyEapMethodPeapInfo &info, KyWirelessConnectSetting &connSettingInfo, + QString & devIface, bool isHidden); + void addAndActiveWirelessEnterPriseTtlsConnect(KyEapMethodTtlsInfo &info, KyWirelessConnectSetting &connSettingInfo, + QString & devIface, bool isHidden); + //属性页 page1 AutoConnect + void setWirelessAutoConnect(const QString &uuid, bool bAutoConnect); + //属性页 page2 page3 ipv6 + void updateIpv4AndIpv6SettingInfo(const QString &uuid, const KyConnectSetting &connectSettingsInfo); + //属性页 page4 wifi Security + //连接修改(安全改为个人/None) + void updateWirelessPersonalConnect(const QString &uuid, const KyWirelessConnectSetting &connSettingInfo, bool bPwdChange); + //连接修改(安全改为改为企业) + void updateWirelessEnterPriseTlsConnect(const QString &uuid, const KyEapMethodTlsInfo &tlsinfo); + void updateWirelessEnterPrisePeapConnect(const QString &uuid, const KyEapMethodPeapInfo &peapInfo); + void updateWirelessEnterPriseTtlsConnect(const QString &uuid, const KyEapMethodTtlsInfo &ttlsInfo); + //忘记 + void deleteWirelessConnect(const QString &connectUuid); + //获取密码 + QString getPsk(const QString &connectUuid); + QString getPrivateKeyPassword(const QString &connectUuid); + QString get8021xPassword(const QString &connectUuid); + + //申请扫描 + void requestWirelessScan(); + + void activeWirelessAp(const QString apUuid, const QString apName, + const QString apPassword, const QString apDevice, + const QString wirelessBand); + void deactiveWirelessAp(const QString apName, const QString apUuid); + +private: + NetworkManager::ConnectionSettings::Ptr createWirelessApSetting(const QString apSsid, + const QString apPassword, + const QString apDevice, + const QString wirelessBand); + void updateWirelessApSetting(NetworkManager::Connection::Ptr apConnectPtr, + const QString apName, + const QString apPassword, + const QString apDevice, + const QString wirelessBand); + +signals: + void wifiEnabledChanged(bool); + void enabledWirelessNetwork(bool enabled); + void addAndActivateConnectionError(QString errorMessage); + +private: + NetworkManager::WirelessNetwork::Ptr checkWifiNetExist(QString ssid, QString devName); + void updateWirelessSecu(NetworkManager::ConnectionSettings::Ptr connSettingPtr, const KyWirelessConnectSetting &connSettingInfo, bool bPwdChange = false); + void setIpv4AndIpv6Setting(NetworkManager::ConnectionSettings::Ptr connSetting, const KyConnectSetting &connSettingInfo); + void setWirelessSecuWpaXEap(NetworkManager::ConnectionSettings::Ptr connSettingPtr); + void activateApConnectionByUuid(const QString apUuid, const QString apDevice); +}; + +#endif // KYWIRELESSCONNECTOPERATION_H diff --git a/src/backend/dbus-interface/kywirelessnetitem.cpp b/src/backend/dbus-interface/kywirelessnetitem.cpp new file mode 100644 index 00000000..a1d4606d --- /dev/null +++ b/src/backend/dbus-interface/kywirelessnetitem.cpp @@ -0,0 +1,114 @@ +#include "kywirelessnetitem.h" +#include +#include "kylinutil.h" + +const QString ENTERPRICE_TYPE = "802.1X"; +const QString WPA1_AND_WPA2 = "WPA"; +const QString WPA3 = "WPA3"; + +QString enumToQstring(NetworkManager::AccessPoint::Capabilities cap, NetworkManager::AccessPoint::WpaFlags wpa_flags,NetworkManager::AccessPoint::WpaFlags rsn_flags) +{ + QString out; + if ( (cap & NM_802_11_AP_FLAGS_PRIVACY) + && (wpa_flags == NM_802_11_AP_SEC_NONE) + && (rsn_flags == NM_802_11_AP_SEC_NONE)) { + out += "WEP "; + } + if (wpa_flags != NM_802_11_AP_SEC_NONE) { + out += "WPA1 "; + } + if ((rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK) + || (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) { + out += "WPA2 "; + } + if (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_SAE) { + out += "WPA3 "; + } + if ( (wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) + || (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) { + out += "802.1X "; + } + return out; +} + +KyWirelessNetItem::KyWirelessNetItem(NetworkManager::WirelessNetwork::Ptr net) +{ + m_networkResourceInstance = KyNetworkResourceManager::getInstance(); + + m_bssid = ""; + m_connectUuid = ""; + m_isConfigured = false; + m_connName = ""; + m_connDbusPath = ""; + m_secuType = ""; + m_kySecuType = NONE; + m_device = ""; + m_channel = 0; + + init(net); +} + + +KyWirelessNetItem::~KyWirelessNetItem() +{ + m_networkResourceInstance = nullptr; +} + + +void KyWirelessNetItem::init(NetworkManager::WirelessNetwork::Ptr net) +{ + // m_NetSsid = net->ssid(); + + NetworkManager::AccessPoint::Ptr accessPointPtr = net->referenceAccessPoint(); + QByteArray rawSsid = accessPointPtr->rawSsid(); + m_NetSsid = getSsidFromByteArray(rawSsid); + + m_signalStrength = net->signalStrength(); + m_frequency = net->referenceAccessPoint()->frequency(); + m_channel = NetworkManager::findChannel(m_frequency); + NetworkManager::AccessPoint::Capabilities cap = net->referenceAccessPoint()->capabilities(); + NetworkManager::AccessPoint::WpaFlags wpaFlag = net->referenceAccessPoint()->wpaFlags(); + NetworkManager::AccessPoint::WpaFlags rsnFlag = net->referenceAccessPoint()->rsnFlags(); + m_secuType = enumToQstring(cap, wpaFlag, rsnFlag); + if (m_secuType.indexOf(ENTERPRICE_TYPE) >= 0) { + m_kySecuType = WPA_AND_WPA2_ENTERPRISE; + } else if (m_secuType.indexOf(WPA3) >= 0) { + m_kySecuType = WPA3_PERSONAL; + } else if ( m_secuType.indexOf(WPA1_AND_WPA2) >= 0) { + m_kySecuType = WPA_AND_WPA2_PERSONAL; + } + m_bssid = net->referenceAccessPoint()->hardwareAddress(); + m_device = net->device(); + initInfoBySsid(); +} + +void KyWirelessNetItem::initInfoBySsid() +{ + for (auto const & conn : m_networkResourceInstance->m_connections) { + NetworkManager::ConnectionSettings::Ptr settings = conn->settings(); + if (settings->connectionType() != NetworkManager::ConnectionSettings::Wireless) { + continue; + } + + NetworkManager::WirelessSetting::Ptr wifi_sett + = settings->setting(NetworkManager::Setting::Wireless).dynamicCast(); + QString devName = m_networkResourceInstance->findDeviceUni(m_device)->interfaceName(); + QByteArray rawSsid = wifi_sett->ssid(); + QString wifiSsid = getSsidFromByteArray(rawSsid); + if (wifiSsid == m_NetSsid + && (settings->interfaceName().compare(devName) == 0 || settings->interfaceName().isEmpty())) { + m_connectUuid = settings->uuid(); + m_connName = conn->name(); + m_connDbusPath = conn->path(); + m_isConfigured = true; + /* + * 如果有激活的链接,则取激活的链接,没有则取最后一个,因为一个热点可以创建多个链接 + */ + if (nullptr != m_networkResourceInstance->getActiveConnect(m_connectUuid)) { + break; + } + } + } + + return; +} diff --git a/src/backend/dbus-interface/kywirelessnetitem.h b/src/backend/dbus-interface/kywirelessnetitem.h new file mode 100644 index 00000000..6f7b105b --- /dev/null +++ b/src/backend/dbus-interface/kywirelessnetitem.h @@ -0,0 +1,45 @@ +#ifndef KYWIRELESSNETITEM_H +#define KYWIRELESSNETITEM_H + +#include + +#include "kylinnetworkresourcemanager.h" +#include "kywirelessconnectoperation.h" + +QString enumToQstring(NetworkManager::AccessPoint::Capabilities, NetworkManager::AccessPoint::WpaFlags, NetworkManager::AccessPoint::WpaFlags); + +class KyWirelessNetItem +{ +public: + KyWirelessNetItem(NetworkManager::WirelessNetwork::Ptr net); + KyWirelessNetItem() {;} + ~KyWirelessNetItem(); + +private: + void init(NetworkManager::WirelessNetwork::Ptr net); + void initInfoBySsid(); + +public: + QString m_NetSsid; + QString m_connectUuid; + QString m_bssid; + int m_signalStrength; + uint m_frequency; + QString m_secuType; + KySecuType m_kySecuType; + + //only for m_isConfiged = true + bool m_isConfigured; + QString m_connName; + QString m_connDbusPath; + uint m_channel; + + + +private: + KyNetworkResourceManager *m_networkResourceInstance = nullptr; + QString m_device; + +}; + +#endif // KYWIRELESSNETITEM_H diff --git a/src/backend/dbus-interface/kywirelessnetresource.cpp b/src/backend/dbus-interface/kywirelessnetresource.cpp new file mode 100644 index 00000000..386f863b --- /dev/null +++ b/src/backend/dbus-interface/kywirelessnetresource.cpp @@ -0,0 +1,732 @@ +#include "kywirelessnetresource.h" +#include "kylinutil.h" + +#define LOG_FLAG "[KyWirelessNetResource]" + +static bool subWifiListSort(const KyWirelessNetItem info1, const KyWirelessNetItem info2) +{ + if (info1.m_isConfigured == info2.m_isConfigured) { + if (info1.m_signalStrength != info2.m_signalStrength) { + return info1.m_signalStrength > info2.m_signalStrength; + } else { + if (QString::compare(info1.m_NetSsid, info2.m_NetSsid, Qt::CaseInsensitive) > 0) { + return false; + } else { + return true; + } + } + } + return info1.m_isConfigured; +} + +static void wifiListSort(QList &list) +{ + qSort(list.begin(), list.end(), subWifiListSort); +} + +KyWirelessNetResource::KyWirelessNetResource(QObject *parent) + : QObject(parent) +{ + qDebug()<< LOG_FLAG <<"KyWirelessNetResource"; + + qRegisterMetaType("KyWirelessNetItem&"); + + m_networkResourceInstance = KyNetworkResourceManager::getInstance(); + m_operation = new KyWirelessConnectOperation(this); + m_networkDevice = new KyNetworkDeviceResourse(this); + + kyWirelessNetItemListInit(); + + //TODO:connect device signal + connect(m_networkResourceInstance, &KyNetworkResourceManager::wifiNetworkAdded, + this, &KyWirelessNetResource::onWifiNetworkAdded, Qt::ConnectionType::DirectConnection); + connect(m_networkResourceInstance, &KyNetworkResourceManager::wifiNetworkRemoved, + this, &KyWirelessNetResource::onWifiNetworkRemoved, Qt::ConnectionType::DirectConnection); + connect(m_networkResourceInstance, &KyNetworkResourceManager::wifiNetworkPropertyChange, + this, &KyWirelessNetResource::onWifiNetworkPropertyChange, Qt::ConnectionType::DirectConnection); + connect(m_networkResourceInstance, &KyNetworkResourceManager::wifiNetworkDeviceDisappear, + this, &KyWirelessNetResource::onWifiNetworkDeviceDisappear, Qt::ConnectionType::DirectConnection); + + connect(m_networkResourceInstance, &KyNetworkResourceManager::connectionAdd, + this, &KyWirelessNetResource::onConnectionAdd); + connect(m_networkResourceInstance, &KyNetworkResourceManager::connectionRemove, + this, &KyWirelessNetResource::onConnectionRemove); + connect(m_networkResourceInstance, &KyNetworkResourceManager::connectionUpdate, + this, &KyWirelessNetResource::onConnectionUpdate); + + connect(m_networkDevice, &KyNetworkDeviceResourse::deviceAdd, this, &KyWirelessNetResource::onDeviceAdd); + connect(m_networkDevice, &KyNetworkDeviceResourse::deviceRemove, this, &KyWirelessNetResource::onDeviceRemove); + connect(m_networkDevice, &KyNetworkDeviceResourse::deviceNameUpdate, this, &KyWirelessNetResource::onDeviceNameUpdate); +} + +KyWirelessNetResource::~KyWirelessNetResource() +{ + m_networkResourceInstance = nullptr; +} + +bool KyWirelessNetResource::getAllDeviceWifiNetwork(QMap> &map) +{ +// onWifiNetworkDeviceDisappear(); + if (m_WifiNetworkList.isEmpty()) { + return false; + } else { + QMap >::iterator iter = m_WifiNetworkList.begin(); + while (iter != m_WifiNetworkList.end()) { + wifiListSort(m_WifiNetworkList[iter.key()]); + iter++; + } + map = m_WifiNetworkList; + return true; + } +} + + +bool KyWirelessNetResource::getDeviceWifiNetwork(QString devIfaceName, QList &wirelessNetResource) +{ + if (!m_WifiNetworkList.contains(devIfaceName)) { + return false; + } else { + wifiListSort(m_WifiNetworkList[devIfaceName]); + wirelessNetResource = m_WifiNetworkList[devIfaceName]; + return true; + } +} + +bool KyWirelessNetResource::getWifiNetwork(const QString &devIfaceName, + const QString &ssid, + KyWirelessNetItem &wirelessNetResource) +{ + if (!m_WifiNetworkList.contains(devIfaceName)) { + qDebug()<< LOG_FLAG << "getWifiNetwork fail, not contain " << devIfaceName; + return false; + } else { + for (int index = 0; index < m_WifiNetworkList[devIfaceName].size(); index++){ + if (m_WifiNetworkList[devIfaceName].at(index).m_NetSsid == ssid) { + wirelessNetResource = m_WifiNetworkList[devIfaceName].at(index); + qDebug()<< LOG_FLAG << "getWifiNetwork success"; + return true; + } + } + } + + qDebug()<< LOG_FLAG << "getWifiNetwork fail, not contain " << ssid; + + return false; +} + +void KyWirelessNetResource::getWirelessActiveConnection(NetworkManager::ActiveConnection::State state, QMap &map) +{ + int index = 0; + map.clear(); + NetworkManager::ActiveConnection::List activeConnectionList; + + activeConnectionList.clear(); + activeConnectionList = m_networkResourceInstance->getActiveConnectList(); + if (activeConnectionList.isEmpty()) { + return; + } + + NetworkManager::ActiveConnection::Ptr activeConnectionPtr = nullptr; + for (; index < activeConnectionList.size(); index++) { + activeConnectionPtr = activeConnectionList.at(index); + if (activeConnectionPtr.isNull()) { + continue; + } + + if (NetworkManager::ConnectionSettings::ConnectionType::Wireless != activeConnectionPtr->type()) { + continue; + } + + if (state != activeConnectionPtr->state()) { + continue; + } + + qDebug()<< LOG_FLAG << "getWirelessActiveConnection " << activeConnectionPtr->uuid(); + QString ssid; + QString ifaceName = getDeviceIFace(activeConnectionPtr, ssid); + if(ifaceName.isEmpty() || ssid.isNull()) { + continue; + } + + if (map.contains(ifaceName)) { + map[ifaceName].append(activeConnectionPtr->uuid()); + } else { + QStringList list; + list.append(activeConnectionPtr->uuid()); + map.insert(ifaceName,list); + } + } + + return; +} + +QString KyWirelessNetResource::getActiveConnectSsidByDevice(QString deviceName) +{ + QString ssid = ""; + + NetworkManager::ActiveConnection::List activeConnectionList; + activeConnectionList.clear(); + activeConnectionList = m_networkResourceInstance->getActiveConnectList(); + if (activeConnectionList.isEmpty()) { + return ssid; + } + + NetworkManager::ActiveConnection::Ptr activeConnectionPtr = nullptr; + for (int index = 0; index < activeConnectionList.size(); index++) { + activeConnectionPtr = activeConnectionList.at(index); + if (activeConnectionPtr.isNull()) { + continue; + } + + if (NetworkManager::ConnectionSettings::ConnectionType::Wireless != activeConnectionPtr->type()) { + continue; + } + + if (NetworkManager::ActiveConnection::State::Activated != activeConnectionPtr->state()) { + continue; + } + + QStringList interfaces = activeConnectionPtr->devices(); + if(interfaces.isEmpty()) { + qWarning()<< LOG_FLAG <<"get active device failed."; + continue; + } + + QString ifaceUni = interfaces.at(0); + NetworkManager::Device:: Ptr devicePtr = + m_networkResourceInstance->findDeviceUni(ifaceUni); + if (deviceName != devicePtr->interfaceName()) { + continue; + } + + NetworkManager::Connection::Ptr connectPtr = activeConnectionPtr->connection(); + NetworkManager::ConnectionSettings::Ptr settingPtr = connectPtr->settings(); + NetworkManager::WirelessSetting::Ptr wirelessSettingPtr = + settingPtr->setting(NetworkManager::Setting::Wireless).dynamicCast(); + + QByteArray rawSsid = wirelessSettingPtr->ssid(); + ssid = getSsidFromByteArray(rawSsid); + + break; + } + + return ssid; +} + +bool KyWirelessNetResource::getActiveWirelessNetItem(QString deviceName, KyWirelessNetItem &wirelessNetItem) +{ + if (!m_WifiNetworkList.contains(deviceName)) { + qDebug() << "getWifiNetwork fail,not contain " << deviceName; + return false; + } + + QString ssid = getActiveConnectSsidByDevice(deviceName); + if (ssid.isEmpty()) { + return false; + } + + for (int index = 0; index < m_WifiNetworkList[deviceName].size(); index ++) { + if (m_WifiNetworkList[deviceName].at(index).m_NetSsid == ssid) { + wirelessNetItem = m_WifiNetworkList[deviceName].at(index); + qDebug()<< LOG_FLAG << "getWifiNetwork success"; + return true; + } + } + + return false; +} + +QString KyWirelessNetResource::getDeviceIFace(NetworkManager::ActiveConnection::Ptr actConn, + QString &wirelessNetResourcessid) +{ + if (actConn.isNull()) { + return ""; + } + + NetworkManager::Connection::Ptr conn = actConn->connection(); + if (conn.isNull()) { + return ""; + } + + NetworkManager::ConnectionSettings::Ptr sett = conn->settings(); + if (sett.isNull()) { + return ""; + } + + NetworkManager::WirelessSetting::Ptr wireless_sett = sett->setting(NetworkManager::Setting::Wireless).dynamicCast(); + if (wireless_sett.isNull()) { + return ""; + } + + QByteArray rawSsid = wireless_sett->ssid(); + wirelessNetResourcessid = getSsidFromByteArray(rawSsid); + + QStringList interfaces = actConn->devices(); + if (interfaces.isEmpty()) { + return ""; + } + + QString ifaceUni = interfaces.at(0); + NetworkManager::Device:: Ptr devicePtr = + m_networkResourceInstance->findDeviceUni(ifaceUni); + + return devicePtr->interfaceName(); +} + +void KyWirelessNetResource::getSsidByUuid(const QString uuid, QString &ssid) +{ + ssid.clear(); + NetworkManager::Connection::Ptr connectPtr = m_networkResourceInstance->getConnect(uuid); + if (connectPtr.isNull()) { + return; + } + + NetworkManager::WirelessSetting::Ptr wireless_sett + = connectPtr->settings()->setting(NetworkManager::Setting::Wireless).dynamicCast(); + if (wireless_sett.isNull()) { + qDebug()<< LOG_FLAG << "don't have WirelessSetting connection"; + return; + } + + QByteArray rawSsid = wireless_sett->ssid(); + ssid = getSsidFromByteArray(rawSsid); + + qDebug()<< LOG_FLAG << "getSsidByUuid success " << ssid; + + return; +} + +void KyWirelessNetResource::getDeviceByUuid(const QString uuid, QString &deviceName) +{ + deviceName.clear(); + + NetworkManager::ActiveConnection::Ptr activeConnectionPtr = m_networkResourceInstance->getActiveConnect(uuid); + if (!activeConnectionPtr.isNull()) { + QStringList interfaces = activeConnectionPtr->devices(); + if (interfaces.size() > 0) { + QString ifaceUni = interfaces.at(0); + NetworkManager::Device:: Ptr devicePtr = + m_networkResourceInstance->findDeviceUni(ifaceUni); + deviceName = devicePtr->interfaceName(); + return; + } else { + qDebug() << LOG_FLAG << "get device of active connection failed."; + } + } + + NetworkManager::Connection::Ptr connectPtr = m_networkResourceInstance->getConnect(uuid); + if (connectPtr.isNull()) { + return; + } + + deviceName = connectPtr->settings()->interfaceName(); + + return; +} + +void KyWirelessNetResource::kyWirelessNetItemListInit() +{ + qDebug()<< LOG_FLAG << "wireless net size:" << m_networkResourceInstance->m_wifiNets.size(); + for (auto const & net : m_networkResourceInstance->m_wifiNets) { + QString devIface = getDeviceIFace(net); + if (devIface.isEmpty()) { + continue; + } + + KyWirelessNetItem item(net); + if (!m_WifiNetworkList.contains(devIface)){ + QList list; + list.append(item); + m_WifiNetworkList.insert(devIface,list); + } else { + m_WifiNetworkList[devIface].append(item); + } + } + + return; +} + +QString KyWirelessNetResource::getDeviceIFace(NetworkManager::WirelessNetwork::Ptr net) +{ + if (net.isNull()) { + return ""; + } + + QString devUni = net->device(); + NetworkManager::Device::Ptr dev = m_networkResourceInstance->findDeviceUni(devUni); + if (dev.isNull()) { + qDebug()<< LOG_FLAG << "KyWirelessNetResource: can't find " << net->ssid() << " find in device list"; + return ""; + } + + return dev->interfaceName(); +} + +void KyWirelessNetResource::onWifiNetworkAdded(QString devIfaceName, QString ssid) +{ + + NetworkManager::Device::Ptr dev = m_networkResourceInstance->findDeviceInterface(devIfaceName); + if (dev.isNull()) { + return; + } + + NetworkManager::WirelessDevice* w_dev = qobject_cast(dev.data()); + NetworkManager::WirelessNetwork::Ptr wifi = w_dev->findNetwork(ssid); + + if (wifi.isNull()) { + return; + } + + KyWirelessNetItem item(wifi); + + if (m_WifiNetworkList.contains(devIfaceName)) { + m_WifiNetworkList[devIfaceName].append(item); + } else { + QList list; + list.append(item); + m_WifiNetworkList.insert(devIfaceName,list); + } + + emit wifiNetworkAdd(devIfaceName, item); +} + +void KyWirelessNetResource::onWifiNetworkRemoved(QString devIfaceName, QString ssid) +{ + if (m_WifiNetworkList.contains(devIfaceName)) { + int index = 0; + for ( ; index < m_WifiNetworkList.value(devIfaceName).size(); index++) { + if ( m_WifiNetworkList[devIfaceName].at(index).m_NetSsid == ssid) { + m_WifiNetworkList[devIfaceName].removeAt(index); + } + } + //remove后为空则删除 + if (m_WifiNetworkList.value(devIfaceName).isEmpty()) { + m_WifiNetworkList.remove(devIfaceName); + } + emit wifiNetworkRemove(devIfaceName,ssid); + } +} + +void KyWirelessNetResource::onWifiNetworkPropertyChange(NetworkManager::WirelessNetwork * net) +{ + if (nullptr == net) { + return; + } + + NetworkManager::AccessPoint::Ptr accessPointPtr = net->referenceAccessPoint(); + QByteArray rawSsid = accessPointPtr->rawSsid(); + QString wifiSsid = getSsidFromByteArray(rawSsid); + + if (net->device().isEmpty()) { + return; + } + + QString devIface = m_networkResourceInstance->findDeviceUni(net->device())->interfaceName(); + if (m_WifiNetworkList.contains(devIface)) { + QList::iterator iter = m_WifiNetworkList[devIface].begin(); + while (iter != m_WifiNetworkList[devIface].end()) { + if (iter->m_NetSsid == wifiSsid) { +// qDebug()<< LOG_FLAG <<"recive properity changed signal, sender is" << iter->m_NetSsid; + if (iter->m_signalStrength != net->signalStrength()) { + iter->m_signalStrength = net->signalStrength(); + emit signalStrengthChange(devIface, wifiSsid, iter->m_signalStrength); + } + + if (iter->m_bssid != accessPointPtr->hardwareAddress()) { + iter->m_bssid = accessPointPtr->hardwareAddress(); + emit bssidChange(devIface, wifiSsid, iter->m_bssid); + } + + QString secuType = enumToQstring(accessPointPtr->capabilities(), + accessPointPtr->wpaFlags(), + accessPointPtr->rsnFlags()); + if (iter->m_secuType != secuType) { + iter->m_secuType = secuType; + emit secuTypeChange(devIface, wifiSsid, secuType); + } + + break; + } + iter++; + } + } +} + +void KyWirelessNetResource::onWifiNetworkDeviceDisappear() +{ + m_WifiNetworkList.clear(); + kyWirelessNetItemListInit(); +} + +bool KyWirelessNetResource::getEnterPriseInfoTls(QString &uuid, KyEapMethodTlsInfo &info) +{ + NetworkManager::Connection::Ptr conn = m_networkResourceInstance->getConnect(uuid); + if (conn.isNull()) { + qDebug()<< LOG_FLAG << "modifyEnterPriseInfoTls connection missing"; + return false; + } + + NetworkManager::WirelessSecuritySetting::Ptr security_sett = + conn->settings()->setting(NetworkManager::Setting::WirelessSecurity).dynamicCast(); + if (security_sett.isNull()) { + qDebug()<< LOG_FLAG << "don't have WirelessSecurity connection"; + return false; + } + if (security_sett->keyMgmt() != NetworkManager::WirelessSecuritySetting::WpaEap) { + return false; + } + NetworkManager::Security8021xSetting::Ptr setting = + conn->settings()->setting(NetworkManager::Setting::Security8021x).dynamicCast(); + if (setting.isNull()) { + qDebug()<< LOG_FLAG << "don't have Security8021x connection"; + return false; + } + + + info.identity = setting->identity(); + info.domain = setting->domainSuffixMatch(); + info.caCertPath = setting->caPath(); + if (info.caCertPath.left(7) == "file://") { + info.caCertPath = info.caCertPath.mid(7); + } + + info.clientCertPath = setting->clientCertificate(); + if (info.clientCertPath.left(7) == "file://") { + info.clientCertPath = info.clientCertPath.mid(7); + } + + info.clientPrivateKey = QString(setting->privateKey()); + if (info.clientPrivateKey.left(7) == "file://") { + info.clientPrivateKey = info.clientPrivateKey.mid(7); + } + + info.m_privateKeyPWDFlag = setting->privateKeyPasswordFlags(); + if (!info.m_privateKeyPWDFlag) { + info.clientPrivateKeyPWD = m_operation->getPrivateKeyPassword(conn->uuid()); + } + + return true; +} + +bool KyWirelessNetResource::getEnterPriseInfoPeap(QString &uuid, KyEapMethodPeapInfo &info) +{ + NetworkManager::Connection::Ptr conn = m_networkResourceInstance->getConnect(uuid); + if (conn.isNull()) { + qDebug()<< LOG_FLAG << "getEnterPriseInfoPeap connection missing"; + return false; + } + NetworkManager::WirelessSecuritySetting::Ptr security_sett + = conn->settings()->setting(NetworkManager::Setting::WirelessSecurity).dynamicCast(); + if (security_sett.isNull()) { + qDebug()<< LOG_FLAG << "don't have WirelessSecurity connection"; + return false; + } + + if (security_sett->keyMgmt() != NetworkManager::WirelessSecuritySetting::WpaEap) { + qDebug()<< LOG_FLAG << "keyMgmt not WpaEap " << security_sett->keyMgmt(); + return false; + } + + NetworkManager::Security8021xSetting::Ptr setting = + conn->settings()->setting(NetworkManager::Setting::Security8021x).dynamicCast(); + if (setting.isNull() || !setting->eapMethods().contains(NetworkManager::Security8021xSetting::EapMethod::EapMethodPeap)) { + qDebug()<< LOG_FLAG << "don't have Security8021x connection"; + return false; + } + + info.phase2AuthMethod = (KyNoEapMethodAuth)setting->phase2AuthMethod(); + info.userName = setting->identity(); + info.m_passwdFlag = setting->passwordFlags(); + if (!info.m_passwdFlag) { + info.userPWD = m_operation->get8021xPassword(conn->uuid()); + } + + return true; +} + +bool KyWirelessNetResource::getEnterPriseInfoTtls(QString &uuid, KyEapMethodTtlsInfo &info) +{ + NetworkManager::Connection::Ptr conn = m_networkResourceInstance->getConnect(uuid); + if (conn.isNull()) { + qDebug()<< LOG_FLAG << "modifyEnterPriseInfoTtls connection missing"; + return false; + } + + NetworkManager::WirelessSecuritySetting::Ptr security_sett + = conn->settings()->setting(NetworkManager::Setting::WirelessSecurity).dynamicCast(); + if (security_sett.isNull()) { + qDebug()<< LOG_FLAG << "don't have WirelessSecurity connection"; + return false; + } + if (security_sett->keyMgmt() != NetworkManager::WirelessSecuritySetting::WpaEap) { + qDebug()<< LOG_FLAG << "not wpaeap"<keyMgmt(); + return false; + } + + NetworkManager::Security8021xSetting::Ptr setting = conn->settings()->setting(NetworkManager::Setting::Security8021x).dynamicCast(); + if (setting.isNull() || !setting->eapMethods().contains(NetworkManager::Security8021xSetting::EapMethod::EapMethodTtls)) { + qDebug()<< LOG_FLAG << "don't have Security8021x connection"; + return false; + } + + info.authEapMethod = (KyEapMethodAuth)setting->phase2AuthEapMethod(); + info.authNoEapMethod = (KyNoEapMethodAuth)setting->phase2AuthMethod(); + + info.authType = KyTtlsAuthMethod::AUTH_EAP; + if (info.authEapMethod != KyAuthEapMethodUnknown) { + info.authType = KyTtlsAuthMethod::AUTH_EAP; + } else { + info.authType = KyTtlsAuthMethod::AUTH_NO_EAP; + } + + info.userName = setting->identity(); + info.m_passwdFlag = setting->passwordFlags(); + if (!info.m_passwdFlag) { + info.userPWD = m_operation->get8021xPassword(conn->uuid()); + } + + return true; +} + +void KyWirelessNetResource::onConnectionAdd(QString uuid) +{ + qDebug() << LOG_FLAG << "onConnectionAdd " << uuid; + NetworkManager::Connection::Ptr conn = m_networkResourceInstance->getConnect(uuid); + if (conn.isNull()) { + qDebug()<< LOG_FLAG << "onConnectionAdd can not find connection" << uuid; + return; + } + + NetworkManager::ConnectionSettings::Ptr sett = conn->settings(); + if (sett->connectionType() != NetworkManager::ConnectionSettings::ConnectionType::Wireless) { + qDebug()<< LOG_FLAG << uuid << " is not wireless connection"; + return; + } + NetworkManager::WirelessSetting::Ptr wireless_sett = + sett->setting(NetworkManager::Setting::Wireless).dynamicCast(); + + QByteArray rawSsid = wireless_sett->ssid(); + QString wifiSsid = getSsidFromByteArray(rawSsid); + QMap map; + map.clear(); + QMap >::iterator iter = m_WifiNetworkList.begin(); + while (iter != m_WifiNetworkList.end()) { + for(int i = 0; i < iter.value().size(); i++) { + if (iter.value().at(i).m_NetSsid == wifiSsid + && (sett->interfaceName() == iter.key() || sett->interfaceName().isEmpty())) { + QString devIfaceName; + QString ssid; + m_WifiNetworkList[iter.key()][i].m_isConfigured = true; + m_WifiNetworkList[iter.key()][i].m_connName = conn->name(); + m_WifiNetworkList[iter.key()][i].m_connectUuid = conn->uuid(); + m_WifiNetworkList[iter.key()][i].m_connDbusPath = conn->path(); + m_WifiNetworkList[iter.key()][i].m_channel = wireless_sett->channel(); + + devIfaceName = iter.key(); + ssid = iter.value().at(i).m_NetSsid; + map.insert(devIfaceName, ssid); + + break; + } + } + iter++; + } + + if (!map.isEmpty()) { + for(auto var = map.cbegin(); var != map.cend(); var++) { + QString devIfaceName = var.key(); + QString ssid = var.value(); + emit connectionAdd(devIfaceName, ssid); + } + } +} + +void KyWirelessNetResource::onConnectionRemove(QString path) +{ + qDebug()<< LOG_FLAG << "onConnectionRemove remove " << path; + QMap map; + map.clear(); + + QMap >::iterator iter = m_WifiNetworkList.begin(); + while (iter != m_WifiNetworkList.end()) { + qDebug()<< LOG_FLAG <<"wifi network list key:" << iter.key(); + for(int i = 0; i < iter.value().size(); i++) { + qDebug() << LOG_FLAG << "connection path" << iter.value().at(i).m_connDbusPath; + if (iter.value().at(i).m_connDbusPath == path) { + QString devIfaceName; + QString ssid; + m_WifiNetworkList[iter.key()][i].m_isConfigured = false; + m_WifiNetworkList[iter.key()][i].m_connName = ""; + m_WifiNetworkList[iter.key()][i].m_connectUuid = ""; + m_WifiNetworkList[iter.key()][i].m_connDbusPath = ""; + m_WifiNetworkList[iter.key()][i].m_channel = 0; + + devIfaceName = iter.key(); + ssid = iter.value().at(i).m_NetSsid; + map.insert(devIfaceName, ssid); + break; + } + } + iter++; + } + + if (!map.isEmpty()) { + for(auto var = map.cbegin(); var != map.cend(); var++) { + QString devIfaceName = var.key(); + QString ssid = var.value(); + emit connectionRemove(devIfaceName, ssid); + } + } + +} + + +void KyWirelessNetResource::onConnectionUpdate(QString uuid) +{ + qDebug()<< LOG_FLAG << "onConnectionUpdate " << uuid; + NetworkManager::Connection::Ptr conn = m_networkResourceInstance->getConnect(uuid); + if (conn.isNull()) { + qDebug()<< LOG_FLAG << "onConnectionAdd can not find connection" << uuid; + return; + } + + NetworkManager::ConnectionSettings::Ptr sett= conn->settings(); + if (sett->connectionType() != NetworkManager::ConnectionSettings::ConnectionType::Wireless) { + return; + } + + m_WifiNetworkList.clear(); + kyWirelessNetItemListInit(); + emit wifiNetworkUpdate(); +} + + +void KyWirelessNetResource::onDeviceAdd(QString deviceName, NetworkManager::Device::Type deviceType) +{ + if(deviceType == NetworkManager::Device::Type::Wifi) { + if (!m_WifiNetworkList.contains(deviceName)) { + m_WifiNetworkList.insert(deviceName,QList()); + } + } +} + +void KyWirelessNetResource::onDeviceRemove(QString deviceName) +{ + if (m_WifiNetworkList.contains(deviceName)) { + m_WifiNetworkList.remove(deviceName); + } +} + +void KyWirelessNetResource::onDeviceNameUpdate(QString oldName, QString newName) +{ + if (!m_WifiNetworkList.contains(oldName)) { + return; + } + + QMap> newWifiNetworkList(m_WifiNetworkList); + QList list = m_WifiNetworkList[oldName]; + newWifiNetworkList.remove(oldName); + newWifiNetworkList.insert(newName,list); + m_WifiNetworkList = newWifiNetworkList; + +} diff --git a/src/backend/dbus-interface/kywirelessnetresource.h b/src/backend/dbus-interface/kywirelessnetresource.h new file mode 100644 index 00000000..c7ed1f0b --- /dev/null +++ b/src/backend/dbus-interface/kywirelessnetresource.h @@ -0,0 +1,76 @@ +#ifndef KYWIRELESSNETRESOURCE_H +#define KYWIRELESSNETRESOURCE_H + +#include +#include "kywirelessnetitem.h" +#include "kylinnetworkresourcemanager.h" +#include "kyenterpricesettinginfo.h" +#include "kylinconnectresource.h" +#include "kywirelessconnectoperation.h" +#include "kylinnetworkdeviceresource.h" + + +//class KyWirelessNetItem; + +class KyWirelessNetResource : public QObject +{ + Q_OBJECT +public: + explicit KyWirelessNetResource(QObject *parent = nullptr); + ~KyWirelessNetResource(); + + //ui层调用接口 + bool getWifiNetwork(const QString &devIfaceName, const QString &ssid, KyWirelessNetItem &wirelessNetResource); + bool getAllDeviceWifiNetwork(QMap> &map); + bool getDeviceWifiNetwork(QString devIfaceName, QList &wirelessNetResource); + + bool getEnterPriseInfoTls(QString &uuid, KyEapMethodTlsInfo &info); + bool getEnterPriseInfoPeap(QString &uuid, KyEapMethodPeapInfo &info); + bool getEnterPriseInfoTtls(QString &uuid, KyEapMethodTtlsInfo &info); + + void getWirelessActiveConnection(NetworkManager::ActiveConnection::State state, QMap &map); + bool getActiveWirelessNetItem(QString deviceName, KyWirelessNetItem &wirelessNetItem); + + QString getActiveConnectSsidByDevice(QString deviceName); + void getSsidByUuid(const QString uuid, QString &ssid); + void getDeviceByUuid(const QString uuid, QString &deviceName); + + +private: + void kyWirelessNetItemListInit(); + QString getDeviceIFace(NetworkManager::WirelessNetwork::Ptr net); + QString getDeviceIFace(NetworkManager::ActiveConnection::Ptr actConn, QString &wirelessNetResourcessid); + +public slots: + void onWifiNetworkAdded(QString, QString); + void onWifiNetworkRemoved(QString, QString); + void onWifiNetworkPropertyChange(NetworkManager::WirelessNetwork * net); + void onWifiNetworkDeviceDisappear(); + + void onConnectionAdd(QString uuid); + void onConnectionUpdate(QString uuid); + void onConnectionRemove(QString); + + void onDeviceAdd(QString deviceName, NetworkManager::Device::Type deviceType); + void onDeviceRemove(QString deviceName); + void onDeviceNameUpdate(QString oldName, QString newName); + +signals: + void signalStrengthChange(QString, QString, int); + void bssidChange(QString, QString, QString); + void secuTypeChange(QString, QString, QString); + void connectionRemove(QString, QString); + void connectionAdd(QString, QString); + void wifiNetworkUpdate(); + void wifiNetworkAdd(QString, KyWirelessNetItem&); + void wifiNetworkRemove(QString, QString); + +private: + KyNetworkResourceManager *m_networkResourceInstance = nullptr; + KyWirelessConnectOperation *m_operation = nullptr; + KyNetworkDeviceResourse *m_networkDevice = nullptr; + QMap > m_WifiNetworkList; + +}; + +#endif // KYWIRELESSNETRESOURCE_H diff --git a/src/backend/dbus-interface/nm-macros-internal.h b/src/backend/dbus-interface/nm-macros-internal.h new file mode 100644 index 00000000..300ff43e --- /dev/null +++ b/src/backend/dbus-interface/nm-macros-internal.h @@ -0,0 +1,1291 @@ +#ifndef __NM_MACROS_INTERNAL_H__ +#define __NM_MACROS_INTERNAL_H__ + +#include +#include +#include + +#define _nm_packed __attribute__ ((packed)) +#define _nm_unused __attribute__ ((unused)) +#define _nm_pure __attribute__ ((pure)) +#define _nm_const __attribute__ ((const)) +#define _nm_printf(a,b) __attribute__ ((__format__ (__printf__, a, b))) +#define _nm_align(s) __attribute__ ((aligned (s))) +#define _nm_alignof(type) __alignof (type) +#define _nm_alignas(type) _nm_align (_nm_alignof (type)) + +#if __GNUC__ >= 7 +#define _nm_fallthrough __attribute__ ((fallthrough)) +#else +#define _nm_fallthrough +#endif + +/*****************************************************************************/ + +#ifdef thread_local +#define _nm_thread_local thread_local +/* + * Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__ + * see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769 + */ +#elif __STDC_VERSION__ >= 201112L && !(defined(__STDC_NO_THREADS__) || (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16)) +#define _nm_thread_local _Thread_local +#else +#define _nm_thread_local __thread +#endif + +/*****************************************************************************/ + +#if 0 +#include "nm-glib.h" + +/*****************************************************************************/ + +#define nm_offsetofend(t,m) (G_STRUCT_OFFSET (t,m) + sizeof (((t *) NULL)->m)) + +#define nm_auto(fcn) __attribute__ ((cleanup(fcn))) + +static inline int nm_close (int fd); + +/** + * nm_auto_free: + * + * Call free() on a variable location when it goes out of scope. + */ +#define nm_auto_free nm_auto(_nm_auto_free_impl) +GS_DEFINE_CLEANUP_FUNCTION(void*, _nm_auto_free_impl, free) + +static inline void +nm_free_secret (char *secret) +{ + if (secret) { + memset (secret, 0, strlen (secret)); + g_free (secret); + } +} + +static inline void +_nm_auto_free_secret_impl (char **v) +{ + nm_free_secret (*v); +} + +/** + * nm_auto_free_secret: + * + * Call g_free() on a variable location when it goes out of scope. + * Also, previously, calls memset(loc, 0, strlen(loc)) to clear out + * the secret. + */ +#define nm_auto_free_secret nm_auto(_nm_auto_free_secret_impl) + +static inline void +_nm_auto_unset_gvalue_impl (GValue *v) +{ + g_value_unset (v); +} +#define nm_auto_unset_gvalue nm_auto(_nm_auto_unset_gvalue_impl) + +static inline void +_nm_auto_unref_gtypeclass (gpointer v) +{ + if (v && *((gpointer *) v)) + g_type_class_unref (*((gpointer *) v)); +} +#define nm_auto_unref_gtypeclass nm_auto(_nm_auto_unref_gtypeclass) + +static inline void +_nm_auto_free_gstring_impl (GString **str) +{ + if (*str) + g_string_free (*str, TRUE); +} +#define nm_auto_free_gstring nm_auto(_nm_auto_free_gstring_impl) + +static inline void +_nm_auto_close_impl (int *pfd) +{ + if (*pfd >= 0) { + int errsv = errno; + + (void) nm_close (*pfd); + errno = errsv; + } +} +#define nm_auto_close nm_auto(_nm_auto_close_impl) + +static inline void +_nm_auto_fclose_impl (FILE **pfd) +{ + if (*pfd) { + int errsv = errno; + + (void) fclose (*pfd); + errno = errsv; + } +} +#define nm_auto_fclose nm_auto(_nm_auto_fclose_impl) + +static inline void +_nm_auto_protect_errno (int *p_saved_errno) +{ + errno = *p_saved_errno; +} +#define NM_AUTO_PROTECT_ERRNO(errsv_saved) nm_auto(_nm_auto_protect_errno) _nm_unused const int errsv_saved = (errno) + +#endif + +/*****************************************************************************/ + +/* http://stackoverflow.com/a/11172679 */ +#define _NM_UTILS_MACRO_FIRST(...) __NM_UTILS_MACRO_FIRST_HELPER(__VA_ARGS__, throwaway) +#define __NM_UTILS_MACRO_FIRST_HELPER(first, ...) first + +#define _NM_UTILS_MACRO_REST(...) __NM_UTILS_MACRO_REST_HELPER(__NM_UTILS_MACRO_REST_NUM(__VA_ARGS__), __VA_ARGS__) +#define __NM_UTILS_MACRO_REST_HELPER(qty, ...) __NM_UTILS_MACRO_REST_HELPER2(qty, __VA_ARGS__) +#define __NM_UTILS_MACRO_REST_HELPER2(qty, ...) __NM_UTILS_MACRO_REST_HELPER_##qty(__VA_ARGS__) +#define __NM_UTILS_MACRO_REST_HELPER_ONE(first) +#define __NM_UTILS_MACRO_REST_HELPER_TWOORMORE(first, ...) , __VA_ARGS__ +#define __NM_UTILS_MACRO_REST_NUM(...) \ + __NM_UTILS_MACRO_REST_SELECT_30TH(__VA_ARGS__, \ + TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\ + TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\ + TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\ + TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\ + TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\ + TWOORMORE, TWOORMORE, TWOORMORE, ONE, throwaway) +#define __NM_UTILS_MACRO_REST_SELECT_30TH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, ...) a30 + +/*****************************************************************************/ + +/* http://stackoverflow.com/a/2124385/354393 */ + +#define NM_NARG(...) \ + _NM_NARG(__VA_ARGS__,_NM_NARG_RSEQ_N()) +#define _NM_NARG(...) \ + _NM_NARG_ARG_N(__VA_ARGS__) +#define _NM_NARG_ARG_N( \ + _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \ + _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \ + _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \ + _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \ + _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \ + _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \ + _61,_62,_63,N,...) N +#define _NM_NARG_RSEQ_N() \ + 63,62,61,60, \ + 59,58,57,56,55,54,53,52,51,50, \ + 49,48,47,46,45,44,43,42,41,40, \ + 39,38,37,36,35,34,33,32,31,30, \ + 29,28,27,26,25,24,23,22,21,20, \ + 19,18,17,16,15,14,13,12,11,10, \ + 9,8,7,6,5,4,3,2,1,0 + +/*****************************************************************************/ + +#if defined (__GNUC__) +#define _NM_PRAGMA_WARNING_DO(warning) G_STRINGIFY(GCC diagnostic ignored warning) +#elif defined (__clang__) +#define _NM_PRAGMA_WARNING_DO(warning) G_STRINGIFY(clang diagnostic ignored warning) +#endif + +/* you can only suppress a specific warning that the compiler + * understands. Otherwise you will get another compiler warning + * about invalid pragma option. + * It's not that bad however, because gcc and clang often have the + * same name for the same warning. */ + +#if defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#define NM_PRAGMA_WARNING_DISABLE(warning) \ + _Pragma("GCC diagnostic push") \ + _Pragma(_NM_PRAGMA_WARNING_DO(warning)) +#elif defined (__clang__) +#define NM_PRAGMA_WARNING_DISABLE(warning) \ + _Pragma("clang diagnostic push") \ + _Pragma(_NM_PRAGMA_WARNING_DO(warning)) +#else +#define NM_PRAGMA_WARNING_DISABLE(warning) +#endif + +#if defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#define NM_PRAGMA_WARNING_REENABLE \ + _Pragma("GCC diagnostic pop") +#elif defined (__clang__) +#define NM_PRAGMA_WARNING_REENABLE \ + _Pragma("clang diagnostic pop") +#else +#define NM_PRAGMA_WARNING_REENABLE +#endif + +/*****************************************************************************/ + +/** + * NM_G_ERROR_MSG: + * @error: (allow-none): the #GError instance + * + * All functions must follow the convention that when they + * return a failure, they must also set the GError to a valid + * message. For external API however, we want to be extra + * careful before accessing the error instance. Use NM_G_ERROR_MSG() + * which is safe to use on NULL. + * + * Returns: the error message. + **/ +static inline const char * +NM_G_ERROR_MSG (GError *error) +{ + return error ? (error->message ? : "(null)") : "(no-error)"; \ +} + +/*****************************************************************************/ + +/* macro to return strlen() of a compile time string. */ +#define NM_STRLEN(str) ( sizeof ("" str) - 1 ) + +/* returns the length of a NULL terminated array of pointers, + * like g_strv_length() does. The difference is: + * - it operats on arrays of pointers (of any kind, requiring no cast). + * - it accepts NULL to return zero. */ +#define NM_PTRARRAY_LEN(array) \ + ({ \ + typeof (*(array)) *const _array = (array); \ + gsize _n = 0; \ + \ + if (_array) { \ + _nm_unused typeof (*(_array[0])) *_array_check = _array[0]; \ + while (_array[_n]) \ + _n++; \ + } \ + _n; \ + }) + +/* Note: @value is only evaluated when *out_val is present. + * Thus, + * NM_SET_OUT (out_str, g_strdup ("hallo")); + * does the right thing. + */ +#define NM_SET_OUT(out_val, value) \ + G_STMT_START { \ + typeof(*(out_val)) *_out_val = (out_val); \ + \ + if (_out_val) { \ + *_out_val = (value); \ + } \ + } G_STMT_END + +/*****************************************************************************/ + +#ifndef _NM_CC_SUPPORT_AUTO_TYPE +#if (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9 ))) +#define _NM_CC_SUPPORT_AUTO_TYPE 1 +#else +#define _NM_CC_SUPPORT_AUTO_TYPE 0 +#endif +#endif + +#ifndef _NM_CC_SUPPORT_GENERIC +#if (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9 ))) || (defined (__clang__)) +#define _NM_CC_SUPPORT_GENERIC 1 +#else +#define _NM_CC_SUPPORT_GENERIC 0 +#endif +#endif + +#if _NM_CC_SUPPORT_AUTO_TYPE +#define _nm_auto_type __auto_type +#endif + +#if _NM_CC_SUPPORT_GENERIC +#define _NM_CONSTCAST_FULL_1(type, obj_expr, obj) \ + (_Generic ((obj_expr), \ + const void *const: ((const type *) (obj)), \ + const void * : ((const type *) (obj)), \ + void *const: (( type *) (obj)), \ + void * : (( type *) (obj)), \ + const type *const: ((const type *) (obj)), \ + const type * : ((const type *) (obj)), \ + type *const: (( type *) (obj)), \ + type * : (( type *) (obj)))) +#define _NM_CONSTCAST_FULL_2(type, obj_expr, obj, alias_type2) \ + (_Generic ((obj_expr), \ + const void *const: ((const type *) (obj)), \ + const void * : ((const type *) (obj)), \ + void *const: (( type *) (obj)), \ + void * : (( type *) (obj)), \ + const alias_type2 *const: ((const type *) (obj)), \ + const alias_type2 * : ((const type *) (obj)), \ + alias_type2 *const: (( type *) (obj)), \ + alias_type2 * : (( type *) (obj)), \ + const type *const: ((const type *) (obj)), \ + const type * : ((const type *) (obj)), \ + type *const: (( type *) (obj)), \ + type * : (( type *) (obj)))) +#define _NM_CONSTCAST_FULL_3(type, obj_expr, obj, alias_type2, alias_type3) \ + (_Generic ((obj_expr), \ + const void *const: ((const type *) (obj)), \ + const void * : ((const type *) (obj)), \ + void *const: (( type *) (obj)), \ + void * : (( type *) (obj)), \ + const alias_type2 *const: ((const type *) (obj)), \ + const alias_type2 * : ((const type *) (obj)), \ + alias_type2 *const: (( type *) (obj)), \ + alias_type2 * : (( type *) (obj)), \ + const alias_type3 *const: ((const type *) (obj)), \ + const alias_type3 * : ((const type *) (obj)), \ + alias_type3 *const: (( type *) (obj)), \ + alias_type3 * : (( type *) (obj)), \ + const type *const: ((const type *) (obj)), \ + const type * : ((const type *) (obj)), \ + type *const: (( type *) (obj)), \ + type * : (( type *) (obj)))) +#define _NM_CONSTCAST_FULL_4(type, obj_expr, obj, alias_type2, alias_type3, alias_type4) \ + (_Generic ((obj_expr), \ + const void *const: ((const type *) (obj)), \ + const void * : ((const type *) (obj)), \ + void *const: (( type *) (obj)), \ + void * : (( type *) (obj)), \ + const alias_type2 *const: ((const type *) (obj)), \ + const alias_type2 * : ((const type *) (obj)), \ + alias_type2 *const: (( type *) (obj)), \ + alias_type2 * : (( type *) (obj)), \ + const alias_type3 *const: ((const type *) (obj)), \ + const alias_type3 * : ((const type *) (obj)), \ + alias_type3 *const: (( type *) (obj)), \ + alias_type3 * : (( type *) (obj)), \ + const alias_type4 *const: ((const type *) (obj)), \ + const alias_type4 * : ((const type *) (obj)), \ + alias_type4 *const: (( type *) (obj)), \ + alias_type4 * : (( type *) (obj)), \ + const type *const: ((const type *) (obj)), \ + const type * : ((const type *) (obj)), \ + type *const: (( type *) (obj)), \ + type * : (( type *) (obj)))) +#define _NM_CONSTCAST_FULL_x(type, obj_expr, obj, n, ...) (_NM_CONSTCAST_FULL_##n (type, obj_expr, obj, ##__VA_ARGS__)) +#define _NM_CONSTCAST_FULL_y(type, obj_expr, obj, n, ...) (_NM_CONSTCAST_FULL_x (type, obj_expr, obj, n, ##__VA_ARGS__)) +#define NM_CONSTCAST_FULL( type, obj_expr, obj, ...) (_NM_CONSTCAST_FULL_y (type, obj_expr, obj, NM_NARG (dummy, ##__VA_ARGS__), ##__VA_ARGS__)) +#else +#define NM_CONSTCAST_FULL( type, obj_expr, obj, ...) ((type *) (obj)) +#endif + +#define NM_CONSTCAST(type, obj, ...) \ + NM_CONSTCAST_FULL(type, (obj), (obj), ##__VA_ARGS__) + +#define NM_GOBJECT_CAST(type, obj, is_check, ...) \ + ({ \ + const void *_obj = (obj); \ + \ + nm_assert (_obj || (is_check (_obj))); \ + NM_CONSTCAST_FULL (type, (obj), _obj, GObject, ##__VA_ARGS__); \ + }) + +#define NM_GOBJECT_CAST_NON_NULL(type, obj, is_check, ...) \ + ({ \ + const void *_obj = (obj); \ + \ + nm_assert (is_check (_obj)); \ + NM_CONSTCAST_FULL (type, (obj), _obj, GObject, ##__VA_ARGS__); \ + }) + +#if _NM_CC_SUPPORT_GENERIC +/* returns @value, if the type of @value matches @type. + * This requires support for C11 _Generic(). If no support is + * present, this returns @value directly. + * + * It's useful to check the let the compiler ensure that @value is + * of a certain type. */ +#define _NM_ENSURE_TYPE(type, value) (_Generic ((value), type: (value))) +#else +#define _NM_ENSURE_TYPE(type, value) (value) +#endif + +#if _NM_CC_SUPPORT_GENERIC +#define NM_PROPAGATE_CONST(test_expr, ptr) \ + (_Generic ((test_expr), \ + const typeof (*(test_expr)) *: ((const typeof (*(ptr)) *) (ptr)), \ + default: (_Generic ((test_expr), \ + typeof (*(test_expr)) *: (ptr))))) +#else +#define NM_PROPAGATE_CONST(test_expr, ptr) (ptr) +#endif + +/*****************************************************************************/ + +#define _NM_IN_SET_EVAL_1( op, _x, y) (_x == (y)) +#define _NM_IN_SET_EVAL_2( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_1 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_3( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_2 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_4( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_3 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_5( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_4 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_6( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_5 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_7( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_6 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_8( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_7 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_9( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_8 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_10(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_9 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_11(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_10 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_12(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_11 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_13(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_12 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_14(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_13 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_15(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_14 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_16(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_15 (op, _x, __VA_ARGS__) + +#define _NM_IN_SET_EVAL_N2(op, _x, n, ...) (_NM_IN_SET_EVAL_##n(op, _x, __VA_ARGS__)) +#define _NM_IN_SET_EVAL_N(op, type, x, n, ...) \ + ({ \ + type _x = (x); \ + \ + /* trigger a -Wenum-compare warning */ \ + nm_assert (TRUE || _x == (x)); \ + \ + !!_NM_IN_SET_EVAL_N2(op, _x, n, __VA_ARGS__); \ + }) + +#define _NM_IN_SET(op, type, x, ...) _NM_IN_SET_EVAL_N(op, type, x, NM_NARG (__VA_ARGS__), __VA_ARGS__) + +/* Beware that this does short-circuit evaluation (use "||" instead of "|") + * which has a possibly unexpected non-function-like behavior. + * Use NM_IN_SET_SE if you need all arguments to be evaluted. */ +#define NM_IN_SET(x, ...) _NM_IN_SET(||, typeof (x), x, __VA_ARGS__) + +/* "SE" stands for "side-effect". Contrary to NM_IN_SET(), this does not do + * short-circuit evaluation, which can make a difference if the arguments have + * side-effects. */ +#define NM_IN_SET_SE(x, ...) _NM_IN_SET(|, typeof (x), x, __VA_ARGS__) + +/* the *_TYPED forms allow to explicitly select the type of "x". This is useful + * if "x" doesn't support typeof (bitfields) or you want to gracefully convert + * a type using automatic type conversion rules (but not forcing the conversion + * with a cast). */ +#define NM_IN_SET_TYPED(type, x, ...) _NM_IN_SET(||, type, x, __VA_ARGS__) +#define NM_IN_SET_SE_TYPED(type, x, ...) _NM_IN_SET(|, type, x, __VA_ARGS__) + +/*****************************************************************************/ + +static inline gboolean +_NM_IN_STRSET_streq (const char *x, const char *s) +{ + return s && strcmp (x, s) == 0; +} + +#define _NM_IN_STRSET_EVAL_1( op, _x, y) _NM_IN_STRSET_streq (_x, y) +#define _NM_IN_STRSET_EVAL_2( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_1 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_3( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_2 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_4( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_3 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_5( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_4 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_6( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_5 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_7( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_6 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_8( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_7 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_9( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_8 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_10(op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_9 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_11(op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_10 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_12(op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_11 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_13(op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_12 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_14(op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_13 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_15(op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_14 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_16(op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_15 (op, _x, __VA_ARGS__) + +#define _NM_IN_STRSET_EVAL_N2(op, _x, n, ...) (_NM_IN_STRSET_EVAL_##n(op, _x, __VA_ARGS__)) +#define _NM_IN_STRSET_EVAL_N(op, x, n, ...) \ + ({ \ + const char *_x = (x); \ + ( ((_x == NULL) && _NM_IN_SET_EVAL_N2 (op, ((const char *) NULL), n, __VA_ARGS__)) \ + || ((_x != NULL) && _NM_IN_STRSET_EVAL_N2 (op, _x, n, __VA_ARGS__)) \ + ); \ + }) + +/* Beware that this does short-circuit evaluation (use "||" instead of "|") + * which has a possibly unexpected non-function-like behavior. + * Use NM_IN_STRSET_SE if you need all arguments to be evaluted. */ +#define NM_IN_STRSET(x, ...) _NM_IN_STRSET_EVAL_N(||, x, NM_NARG (__VA_ARGS__), __VA_ARGS__) + +/* "SE" stands for "side-effect". Contrary to NM_IN_STRSET(), this does not do + * short-circuit evaluation, which can make a difference if the arguments have + * side-effects. */ +#define NM_IN_STRSET_SE(x, ...) _NM_IN_STRSET_EVAL_N(|, x, NM_NARG (__VA_ARGS__), __VA_ARGS__) + +#define NM_STRCHAR_ALL(str, ch_iter, predicate) \ + ({ \ + gboolean _val = TRUE; \ + const char *_str = (str); \ + \ + if (_str) { \ + for (;;) { \ + const char ch_iter = _str[0]; \ + \ + if (ch_iter != '\0') { \ + if (predicate) {\ + _str++; \ + continue; \ + } \ + _val = FALSE; \ + } \ + break; \ + } \ + } \ + _val; \ + }) + +#define NM_STRCHAR_ANY(str, ch_iter, predicate) \ + ({ \ + gboolean _val = FALSE; \ + const char *_str = (str); \ + \ + if (_str) { \ + for (;;) { \ + const char ch_iter = _str[0]; \ + \ + if (ch_iter != '\0') { \ + if (predicate) { \ + ; \ + } else { \ + _str++; \ + continue; \ + } \ + _val = TRUE; \ + } \ + break; \ + } \ + } \ + _val; \ + }) + +/*****************************************************************************/ + +/* NM_CACHED_QUARK() returns the GQuark for @string, but caches + * it in a static variable to speed up future lookups. + * + * @string must be a string literal. + */ +#define NM_CACHED_QUARK(string) \ + ({ \ + static GQuark _nm_cached_quark = 0; \ + \ + (G_LIKELY (_nm_cached_quark != 0) \ + ? _nm_cached_quark \ + : (_nm_cached_quark = g_quark_from_static_string (""string""))); \ + }) + +/* NM_CACHED_QUARK_FCN() is essentially the same as G_DEFINE_QUARK + * with two differences: + * - @string must be a quoted string-literal + * - @fcn must be the full function name, while G_DEFINE_QUARK() appends + * "_quark" to the function name. + * Both properties of G_DEFINE_QUARK() are non favorable, because you can no + * longer grep for string/fcn -- unless you are aware that you are searching + * for G_DEFINE_QUARK() and omit quotes / append _quark(). With NM_CACHED_QUARK_FCN(), + * ctags/cscope can locate the use of @fcn (though it doesn't recognize that + * NM_CACHED_QUARK_FCN() defines it). + */ +#define NM_CACHED_QUARK_FCN(string, fcn) \ +GQuark \ +fcn (void) \ +{ \ + return NM_CACHED_QUARK (string); \ +} + +/*****************************************************************************/ + +#define nm_streq(s1, s2) (strcmp (s1, s2) == 0) +#define nm_streq0(s1, s2) (g_strcmp0 (s1, s2) == 0) + +/*****************************************************************************/ + +static inline GString * +nm_gstring_prepare (GString **l) +{ + if (*l) + g_string_set_size (*l, 0); + else + *l = g_string_sized_new (30); + return *l; +} + +static inline const char * +nm_str_not_empty (const char *str) +{ + return str && str[0] ? str : NULL; +} + +static inline char * +nm_strdup_not_empty (const char *str) +{ + return str && str[0] ? g_strdup (str) : NULL; +} + +static inline char * +nm_str_realloc (char *str) +{ + gs_free char *s = str; + + /* Returns a new clone of @str and frees @str. The point is that @str + * possibly points to a larger chunck of memory. We want to freshly allocate + * a buffer. + * + * We could use realloc(), but that might not do anything or leave + * @str in its memory pool for chunks of a different size (bad for + * fragmentation). + * + * This is only useful when we want to keep the buffer around for a long + * time and want to re-allocate a more optimal buffer. */ + + return g_strdup (s); +} + +/*****************************************************************************/ + +#define NM_PRINT_FMT_QUOTED(cond, prefix, str, suffix, str_else) \ + (cond) ? (prefix) : "", \ + (cond) ? (str) : (str_else), \ + (cond) ? (suffix) : "" +#define NM_PRINT_FMT_QUOTE_STRING(arg) NM_PRINT_FMT_QUOTED((arg), "\"", (arg), "\"", "(null)") + +/*****************************************************************************/ + +/* glib/C provides the following kind of assertions: + * - assert() -- disable with NDEBUG + * - g_return_if_fail() -- disable with G_DISABLE_CHECKS + * - g_assert() -- disable with G_DISABLE_ASSERT + * but they are all enabled by default and usually even production builds have + * these kind of assertions enabled. It also means, that disabling assertions + * is an untested configuration, and might have bugs. + * + * Add our own assertion macro nm_assert(), which is disabled by default and must + * be explicitly enabled. They are useful for more expensive checks or checks that + * depend less on runtime conditions (that is, are generally expected to be true). */ + +#ifndef NM_MORE_ASSERTS +#define NM_MORE_ASSERTS 0 +#endif + +#if NM_MORE_ASSERTS +#define nm_assert(cond) G_STMT_START { g_assert (cond); } G_STMT_END +#define nm_assert_se(cond) G_STMT_START { if (G_LIKELY (cond)) { ; } else { g_assert (FALSE && (cond)); } } G_STMT_END +#define nm_assert_not_reached() G_STMT_START { g_assert_not_reached (); } G_STMT_END +#else +#define nm_assert(cond) G_STMT_START { if (FALSE) { if (cond) { } } } G_STMT_END +#define nm_assert_se(cond) G_STMT_START { if (G_LIKELY (cond)) { ; } } G_STMT_END +#define nm_assert_not_reached() G_STMT_START { ; } G_STMT_END +#endif + +/*****************************************************************************/ + +#define NM_GOBJECT_PROPERTIES_DEFINE_BASE(...) \ +typedef enum { \ + _PROPERTY_ENUMS_0, \ + __VA_ARGS__ \ + _PROPERTY_ENUMS_LAST, \ +} _PropertyEnums; \ +static GParamSpec *obj_properties[_PROPERTY_ENUMS_LAST] = { NULL, } + +#define NM_GOBJECT_PROPERTIES_DEFINE(obj_type, ...) \ +NM_GOBJECT_PROPERTIES_DEFINE_BASE (__VA_ARGS__); \ +static inline void \ +_notify (obj_type *obj, _PropertyEnums prop) \ +{ \ + nm_assert (G_IS_OBJECT (obj)); \ + nm_assert ((gsize) prop < G_N_ELEMENTS (obj_properties)); \ + g_object_notify_by_pspec ((GObject *) obj, obj_properties[prop]); \ +} + +/*****************************************************************************/ + +#define _NM_GET_PRIVATE(self, type, is_check, ...) (&(NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__)->_priv)) +#if _NM_CC_SUPPORT_AUTO_TYPE +#define _NM_GET_PRIVATE_PTR(self, type, is_check, ...) \ + ({ \ + _nm_auto_type _self = NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__); \ + \ + NM_PROPAGATE_CONST (_self, _self->_priv); \ + }) +#else +#define _NM_GET_PRIVATE_PTR(self, type, is_check, ...) (NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__)->_priv) +#endif + +/*****************************************************************************/ + +static inline gpointer +nm_g_object_ref (gpointer obj) +{ + /* g_object_ref() doesn't accept NULL. */ + if (obj) + g_object_ref (obj); + return obj; +} +#define nm_g_object_ref(obj) ((typeof (obj)) nm_g_object_ref (obj)) + +static inline void +nm_g_object_unref (gpointer obj) +{ + /* g_object_unref() doesn't accept NULL. Usully, we workaround that + * by using g_clear_object(), but sometimes that is not convinient + * (for example as as destroy function for a hash table that can contain + * NULL values). */ + if (obj) + g_object_unref (obj); +} + +/* Assigns GObject @obj to destination @pdst, and takes an additional ref. + * The previous value of @pdst is unrefed. + * + * It makes sure to first increase the ref-count of @obj, and handles %NULL + * @obj correctly. + * */ +#define nm_g_object_ref_set(pp, obj) \ + ({ \ + typeof (*(pp)) *const _pp = (pp); \ + typeof (**_pp) *const _obj = (obj); \ + typeof (**_pp) *_p; \ + gboolean _changed = FALSE; \ + \ + if ( _pp \ + && ((_p = *_pp) != _obj)) { \ + if (_obj) { \ + nm_assert (G_IS_OBJECT (_obj)); \ + g_object_ref (_obj); \ + } \ + if (_p) { \ + nm_assert (G_IS_OBJECT (_p)); \ + *_pp = NULL; \ + g_object_unref (_p); \ + } \ + *_pp = _obj; \ + _changed = TRUE; \ + } \ + _changed; \ + }) + +/* basically, replaces + * g_clear_pointer (&location, g_free) + * with + * nm_clear_g_free (&location) + * + * Another advantage is that by using a macro and typeof(), it is more + * typesafe and gives you for example a compiler warning when pp is a const + * pointer or points to a const-pointer. + */ +#define nm_clear_g_free(pp) \ + ({ \ + typeof (*(pp)) *_pp = (pp); \ + typeof (**_pp) *_p; \ + gboolean _changed = FALSE; \ + \ + if ( _pp \ + && (_p = *_pp)) { \ + *_pp = NULL; \ + g_free (_p); \ + _changed = TRUE; \ + } \ + _changed; \ + }) + +#define nm_clear_g_object(pp) \ + ({ \ + typeof (*(pp)) *_pp = (pp); \ + typeof (**_pp) *_p; \ + gboolean _changed = FALSE; \ + \ + if ( _pp \ + && (_p = *_pp)) { \ + nm_assert (G_IS_OBJECT (_p)); \ + *_pp = NULL; \ + g_object_unref (_p); \ + _changed = TRUE; \ + } \ + _changed; \ + }) + +static inline gboolean +nm_clear_g_source (guint *id) +{ + if (id && *id) { + g_source_remove (*id); + *id = 0; + return TRUE; + } + return FALSE; +} + +static inline gboolean +nm_clear_g_signal_handler (gpointer self, gulong *id) +{ + if (id && *id) { + g_signal_handler_disconnect (self, *id); + *id = 0; + return TRUE; + } + return FALSE; +} + +static inline gboolean +nm_clear_g_variant (GVariant **variant) +{ + if (variant && *variant) { + g_variant_unref (*variant); + *variant = NULL; + return TRUE; + } + return FALSE; +} + +static inline gboolean +nm_clear_g_cancellable (GCancellable **cancellable) +{ + if (cancellable && *cancellable) { + g_cancellable_cancel (*cancellable); + g_object_unref (*cancellable); + *cancellable = NULL; + return TRUE; + } + return FALSE; +} + +/*****************************************************************************/ + +/* Determine whether @x is a power of two (@x being an integer type). + * Basically, this returns TRUE, if @x has exactly one bit set. + * For negative values and zero, this always returns FALSE. */ +#define nm_utils_is_power_of_two(x) ({ \ + typeof(x) __x = (x); \ + \ + ( (__x > ((typeof(__x)) 0)) \ + && ((__x & (__x - (((typeof(__x)) 1)))) == ((typeof(__x)) 0))); \ + }) + +/*****************************************************************************/ + +#define NM_UTILS_LOOKUP_DEFAULT(v) return (v) +#define NM_UTILS_LOOKUP_DEFAULT_WARN(v) g_return_val_if_reached (v) +#define NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT(v) { nm_assert_not_reached (); return (v); } +#define NM_UTILS_LOOKUP_ITEM(v, n) (void) 0; case v: return (n); (void) 0 +#define NM_UTILS_LOOKUP_STR_ITEM(v, n) NM_UTILS_LOOKUP_ITEM(v, ""n"") +#define NM_UTILS_LOOKUP_ITEM_IGNORE(v) (void) 0; case v: break; (void) 0 +#define NM_UTILS_LOOKUP_ITEM_IGNORE_OTHER() (void) 0; default: break; (void) 0 + +#define _NM_UTILS_LOOKUP_DEFINE(scope, fcn_name, lookup_type, result_type, unknown_val, ...) \ +scope result_type \ +fcn_name (lookup_type val) \ +{ \ + switch (val) { \ + (void) 0, \ + __VA_ARGS__ \ + (void) 0; \ + }; \ + { unknown_val; } \ +} + +#define NM_UTILS_LOOKUP_STR_DEFINE(fcn_name, lookup_type, unknown_val, ...) \ + _NM_UTILS_LOOKUP_DEFINE (, fcn_name, lookup_type, const char *, unknown_val, __VA_ARGS__) +#define NM_UTILS_LOOKUP_STR_DEFINE_STATIC(fcn_name, lookup_type, unknown_val, ...) \ + _NM_UTILS_LOOKUP_DEFINE (static, fcn_name, lookup_type, const char *, unknown_val, __VA_ARGS__) + +/* Call the string-lookup-table function @fcn_name. If the function returns + * %NULL, the numeric index is converted to string using a alloca() buffer. + * Beware: this macro uses alloca(). */ +#define NM_UTILS_LOOKUP_STR(fcn_name, idx) \ + ({ \ + typeof (idx) _idx = (idx); \ + const char *_s; \ + \ + _s = fcn_name (_idx); \ + if (!_s) { \ + _s = g_alloca (30); \ + \ + g_snprintf ((char *) _s, 30, "(%lld)", (long long) _idx); \ + } \ + _s; \ + }) + +/*****************************************************************************/ + +/* check if @flags has exactly one flag (@check) set. You should call this + * only with @check being a compile time constant and a power of two. */ +#define NM_FLAGS_HAS(flags, check) \ + ( G_STATIC_ASSERT_EXPR ((check) > 0 && ((check) & ((check) - 1)) == 0), NM_FLAGS_ANY ((flags), (check)) ) + +#define NM_FLAGS_ANY(flags, check) ( ( ((flags) & (check)) != 0 ) ? TRUE : FALSE ) +#define NM_FLAGS_ALL(flags, check) ( ( ((flags) & (check)) == (check) ) ? TRUE : FALSE ) + +#define NM_FLAGS_SET(flags, val) ({ \ + const typeof(flags) _flags = (flags); \ + const typeof(flags) _val = (val); \ + \ + _flags | _val; \ + }) + +#define NM_FLAGS_UNSET(flags, val) ({ \ + const typeof(flags) _flags = (flags); \ + const typeof(flags) _val = (val); \ + \ + _flags & (~_val); \ + }) + +#define NM_FLAGS_ASSIGN(flags, val, assign) ({ \ + const typeof(flags) _flags = (flags); \ + const typeof(flags) _val = (val); \ + \ + (assign) \ + ? _flags | (_val) \ + : _flags & (~_val); \ + }) + +/*****************************************************************************/ + +#define _NM_BACKPORT_SYMBOL_IMPL(VERSION, RETURN_TYPE, ORIG_FUNC, VERSIONED_FUNC, ARGS_TYPED, ARGS) \ +RETURN_TYPE VERSIONED_FUNC ARGS_TYPED; \ +RETURN_TYPE VERSIONED_FUNC ARGS_TYPED \ +{ \ + return ORIG_FUNC ARGS; \ +} \ +RETURN_TYPE ORIG_FUNC ARGS_TYPED; \ +__asm__(".symver "G_STRINGIFY(VERSIONED_FUNC)", "G_STRINGIFY(ORIG_FUNC)"@"G_STRINGIFY(VERSION)) + +#define NM_BACKPORT_SYMBOL(VERSION, RETURN_TYPE, FUNC, ARGS_TYPED, ARGS) \ +_NM_BACKPORT_SYMBOL_IMPL(VERSION, RETURN_TYPE, FUNC, _##FUNC##_##VERSION, ARGS_TYPED, ARGS) + +/*****************************************************************************/ + +#define nm_str_skip_leading_spaces(str) \ + ({ \ + typeof (*(str)) *_str = (str); \ + _nm_unused const char *_str_type_check = _str; \ + \ + if (_str) { \ + while (g_ascii_isspace (_str[0])) \ + _str++; \ + } \ + _str; \ + }) + +static inline char * +nm_strstrip (char *str) +{ + /* g_strstrip doesn't like NULL. */ + return str ? g_strstrip (str) : NULL; +} + +static inline const char * +nm_strstrip_avoid_copy (const char *str, char **str_free) +{ + gsize l; + char *s; + + nm_assert (str_free && !*str_free); + + if (!str) + return NULL; + + str = nm_str_skip_leading_spaces (str); + l = strlen (str); + if ( l == 0 + || !g_ascii_isspace (str[l - 1])) + return str; + while ( l > 0 + && g_ascii_isspace (str[l - 1])) + l--; + + s = g_new (char, l + 1); + memcpy (s, str, l); + s[l] = '\0'; + *str_free = s; + return s; +} + +/* g_ptr_array_sort()'s compare function takes pointers to the + * value. Thus, you cannot use strcmp directly. You can use + * nm_strcmp_p(). + * + * Like strcmp(), this function is not forgiving to accept %NULL. */ +static inline int +nm_strcmp_p (gconstpointer a, gconstpointer b) +{ + const char *s1 = *((const char **) a); + const char *s2 = *((const char **) b); + + return strcmp (s1, s2); +} + +/* like nm_strcmp_p(), suitable for g_ptr_array_sort_with_data(). + * g_ptr_array_sort() just casts nm_strcmp_p() to a function of different + * signature. I guess, in glib there are knowledgeable people that ensure + * that this additional argument doesn't cause problems due to different ABI + * for every architecture that glib supports. + * For NetworkManager, we'd rather avoid such stunts. + **/ +static inline int +nm_strcmp_p_with_data (gconstpointer a, gconstpointer b, gpointer user_data) +{ + const char *s1 = *((const char **) a); + const char *s2 = *((const char **) b); + + return strcmp (s1, s2); +} + +static inline int +nm_cmp_uint32_p_with_data (gconstpointer p_a, gconstpointer p_b, gpointer user_data) +{ + const guint32 a = *((const guint32 *) p_a); + const guint32 b = *((const guint32 *) p_b); + + if (a < b) + return -1; + if (a > b) + return 1; + return 0; +} + +/*****************************************************************************/ + +/* Taken from systemd's UNIQ_T and UNIQ macros. */ + +#define NM_UNIQ_T(x, uniq) G_PASTE(__unique_prefix_, G_PASTE(x, uniq)) +#define NM_UNIQ __COUNTER__ + +/*****************************************************************************/ + +/* glib's MIN()/MAX() macros don't have function-like behavior, in that they evaluate + * the argument possibly twice. + * + * Taken from systemd's MIN()/MAX() macros. */ + +#define NM_MIN(a, b) __NM_MIN(NM_UNIQ, a, NM_UNIQ, b) +#define __NM_MIN(aq, a, bq, b) \ + ({ \ + typeof (a) NM_UNIQ_T(A, aq) = (a); \ + typeof (b) NM_UNIQ_T(B, bq) = (b); \ + ((NM_UNIQ_T(A, aq) < NM_UNIQ_T(B, bq)) ? NM_UNIQ_T(A, aq) : NM_UNIQ_T(B, bq)); \ + }) + +#define NM_MAX(a, b) __NM_MAX(NM_UNIQ, a, NM_UNIQ, b) +#define __NM_MAX(aq, a, bq, b) \ + ({ \ + typeof (a) NM_UNIQ_T(A, aq) = (a); \ + typeof (b) NM_UNIQ_T(B, bq) = (b); \ + ((NM_UNIQ_T(A, aq) > NM_UNIQ_T(B, bq)) ? NM_UNIQ_T(A, aq) : NM_UNIQ_T(B, bq)); \ + }) + +#define NM_CLAMP(x, low, high) __NM_CLAMP(NM_UNIQ, x, NM_UNIQ, low, NM_UNIQ, high) +#define __NM_CLAMP(xq, x, lowq, low, highq, high) \ + ({ \ + typeof(x)NM_UNIQ_T(X,xq) = (x); \ + typeof(low) NM_UNIQ_T(LOW,lowq) = (low); \ + typeof(high) NM_UNIQ_T(HIGH,highq) = (high); \ + \ + ( (NM_UNIQ_T(X,xq) > NM_UNIQ_T(HIGH,highq)) \ + ? NM_UNIQ_T(HIGH,highq) \ + : (NM_UNIQ_T(X,xq) < NM_UNIQ_T(LOW,lowq)) \ + ? NM_UNIQ_T(LOW,lowq) \ + : NM_UNIQ_T(X,xq)); \ + }) + +/*****************************************************************************/ + +static inline guint +nm_encode_version (guint major, guint minor, guint micro) +{ + /* analog to the preprocessor macro NM_ENCODE_VERSION(). */ + return (major << 16) | (minor << 8) | micro; +} + +static inline void +nm_decode_version (guint version, guint *major, guint *minor, guint *micro) +{ + *major = (version & 0xFFFF0000u) >> 16; + *minor = (version & 0x0000FF00u) >> 8; + *micro = (version & 0x000000FFu); +} + +/*****************************************************************************/ + +/* taken from systemd's DECIMAL_STR_MAX() + * + * Returns the number of chars needed to format variables of the + * specified type as a decimal string. Adds in extra space for a + * negative '-' prefix (hence works correctly on signed + * types). Includes space for the trailing NUL. */ +#define NM_DECIMAL_STR_MAX(type) \ + (2+(sizeof(type) <= 1 ? 3 : \ + sizeof(type) <= 2 ? 5 : \ + sizeof(type) <= 4 ? 10 : \ + sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)]))) + +/*****************************************************************************/ + +/* if @str is NULL, return "(null)". Otherwise, allocate a buffer using + * alloca() of and fill it with @str. @str will be quoted with double quote. + * If @str is longer then @trunc_at, the string is truncated and the closing + * quote is instead '^' to indicate truncation. + * + * Thus, the maximum stack allocated buffer will be @trunc_at+3. */ +#define nm_strquote_a(trunc_at, str) \ + ({ \ + const char *const _str = (str); \ + \ + (_str \ + ? ({ \ + const gsize _trunc_at = (trunc_at); \ + const gsize _strlen_trunc = NM_MIN (strlen (_str), _trunc_at); \ + char *_buf; \ + \ + _buf = g_alloca (_strlen_trunc + 3); \ + _buf[0] = '"'; \ + memcpy (&_buf[1], _str, _strlen_trunc); \ + _buf[_strlen_trunc + 1] = _str[_strlen_trunc] ? '^' : '"'; \ + _buf[_strlen_trunc + 2] = '\0'; \ + _buf; \ + }) \ + : "(null)"); \ + }) + +#define nm_sprintf_buf(buf, format, ...) \ + ({ \ + char * _buf = (buf); \ + int _buf_len; \ + \ + /* some static assert trying to ensure that the buffer is statically allocated. + * It disallows a buffer size of sizeof(gpointer) to catch that. */ \ + G_STATIC_ASSERT (G_N_ELEMENTS (buf) == sizeof (buf) && sizeof (buf) != sizeof (char *)); \ + _buf_len = g_snprintf (_buf, sizeof (buf), \ + ""format"", ##__VA_ARGS__); \ + nm_assert (_buf_len < sizeof (buf)); \ + _buf; \ + }) + +#define nm_sprintf_bufa(n_elements, format, ...) \ + ({ \ + char *_buf; \ + int _buf_len; \ + typeof (n_elements) _n_elements = (n_elements); \ + \ + _buf = g_alloca (_n_elements); \ + _buf_len = g_snprintf (_buf, _n_elements, \ + ""format"", ##__VA_ARGS__); \ + nm_assert (_buf_len < _n_elements); \ + _buf; \ + }) + +/* aims to alloca() a buffer and fill it with printf(format, name). + * Note that format must not contain any format specifier except + * "%s". + * If the resulting string would be too large for stack allocation, + * it allocates a buffer with g_malloc() and assigns it to *p_val_to_free. */ +#define nm_construct_name_a(format, name, p_val_to_free) \ + ({ \ + const char *const _name = (name); \ + char **const _p_val_to_free = (p_val_to_free); \ + const gsize _name_len = strlen (_name); \ + char *_buf2; \ + \ + nm_assert (_p_val_to_free && !*_p_val_to_free); \ + if (NM_STRLEN (format) + _name_len < 200) \ + _buf2 = nm_sprintf_bufa (NM_STRLEN (format) + _name_len, format, _name); \ + else { \ + _buf2 = g_strdup_printf (format, _name); \ + *_p_val_to_free = _buf2; \ + } \ + (const char *) _buf2; \ + }) + +/*****************************************************************************/ + +/** + * The boolean type _Bool is C99 while we mostly stick to C89. However, _Bool is too + * convinient to miss and is effectively available in gcc and clang. So, just use it. + * + * Usually, one would include "stdbool.h" to get the "bool" define which aliases + * _Bool. We provide this define here, because we want to make use of it anywhere. + * (also, stdbool.h is again C99). + * + * Using _Bool has advantages over gboolean: + * + * - commonly _Bool is one byte large, instead of gboolean's 4 bytes (because gboolean + * is a typedef for gint). Especially when having boolean fields in a struct, we can + * thereby easily save some space. + * + * - _Bool type guarantees that two "true" expressions compare equal. E.g. the follwing + * will not work: + * gboolean v1 = 1; + * gboolean v2 = 2; + * g_assert_cmpint (v1, ==, v2); // will fail + * For that, we often to use !! to coerce gboolean values to 0 or 1: + * g_assert_cmpint (!!v2, ==, TRUE); + * With _Bool type, this will be handled properly by the compiler. + * + * - For structs, we might want to safe even more space and use bitfields: + * struct s1 { + * gboolean v1:1; + * }; + * But the problem here is that gboolean is signed, so that + * v1 will be either 0 or -1 (not 1, TRUE). Thus, the following + * fails: + * struct s1 s = { .v1 = TRUE, }; + * g_assert_cmpint (s1.v1, ==, TRUE); + * It will however work just fine with bool/_Bool while retaining the + * notion of having a boolean value. + * + * Also, add the defines for "true" and "false". Those are nicely highlighted by the editor + * as special types, contrary to glib's "TRUE"/"FALSE". + */ + +#ifndef bool +#define bool _Bool +#define true 1 +#define false 0 +#endif + + +#ifdef _G_BOOLEAN_EXPR +/* g_assert() uses G_LIKELY(), which in turn uses _G_BOOLEAN_EXPR(). + * As glib's implementation uses a local variable _g_boolean_var_, + * we cannot do + * g_assert (some_macro ()); + * where some_macro() itself expands to ({g_assert(); ...}). + * In other words, you cannot have a g_assert() inside a g_assert() + * without getting a -Werror=shadow failure. + * + * Workaround that by re-defining _G_BOOLEAN_EXPR() + **/ +#undef _G_BOOLEAN_EXPR +#define __NM_G_BOOLEAN_EXPR_IMPL(v, expr) \ + ({ \ + int NM_UNIQ_T(V, v); \ + \ + if (expr) \ + NM_UNIQ_T(V, v) = 1; \ + else \ + NM_UNIQ_T(V, v) = 0; \ + NM_UNIQ_T(V, v); \ + }) +#define _G_BOOLEAN_EXPR(expr) __NM_G_BOOLEAN_EXPR_IMPL (NM_UNIQ, expr) +#endif + +/*****************************************************************************/ + +static inline int +nm_steal_fd (int *p_fd) +{ + int fd; + + if ( p_fd + && ((fd = *p_fd) >= 0)) { + *p_fd = -1; + return fd; + } + return -1; +} + +/** + * nm_close: + * + * Like close() but throws an assertion if the input fd is + * invalid. Closing an invalid fd is a programming error, so + * it's better to catch it early. + */ +static inline int +nm_close (int fd) +{ + int r; + + r = close (fd); + nm_assert (r != -1 || fd < 0 || errno != EBADF); + return r; +} + +#endif /* __NM_MACROS_INTERNAL_H__ */ diff --git a/src/backend/dbusadaptor.cpp b/src/backend/dbusadaptor.cpp new file mode 100644 index 00000000..cb637e8e --- /dev/null +++ b/src/backend/dbusadaptor.cpp @@ -0,0 +1,250 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp com.kylin.weather.xml -a dbusadaptor -c DbusAdaptor -l MainWindow + * + * qdbusxml2cpp is Copyright (C) 2015 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#include "dbusadaptor.h" +#include +#include +#include +#include +#include +#include +#include + +const QByteArray GSETTINGS_SCHEMA_KYLIN_NM = "org.ukui.kylin-nm.switch"; +const QString KEY_WIRELESS_SWITCH = "wirelessswitch"; +const QString KEY_WIRED_SWITCH = "wiredswitch"; + +/* + * Implementation of adaptor class DbusAdaptor + */ + +DbusAdaptor::DbusAdaptor(MainWindow *parent) + : QDBusAbstractAdaptor(parent) +{ + // constructor + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >>(); + //setAutoRelaySignals(true)后会自动转发mainwindow发出的同名信号,因此不必再额外写一个转发 + setAutoRelaySignals(true); +} + +DbusAdaptor::~DbusAdaptor() +{ + // destructor +} + +//无线列表 +QMap > DbusAdaptor::getWirelessList() +{ + QMap > map; + parent()->getWirelessList(map); + return map; +} + +//有线列表 +QMap> DbusAdaptor::getWiredList() +{ + QMap> map; + parent()->getWiredList(map); + return map; +} + +//有线开关 +void DbusAdaptor::setWiredSwitchEnable(bool enable) +{ + //todo mainwindow调用backend 对开关 打开/关闭 + if (QGSettings::isSchemaInstalled(GSETTINGS_SCHEMA_KYLIN_NM)) { + QGSettings *gsetting = new QGSettings(GSETTINGS_SCHEMA_KYLIN_NM); + if (gsetting->get(KEY_WIRED_SWITCH).toBool() != enable) { + gsetting->set(KEY_WIRED_SWITCH, enable); + } + delete gsetting; + gsetting = nullptr; + } else { + qDebug()<<"isSchemaInstalled false"; + } +} + +//无线开关 +void DbusAdaptor::setWirelessSwitchEnable(bool enable) +{ + //todo mainwindow调用backend 对开关 打开/关闭 +// if (QGSettings::isSchemaInstalled(GSETTINGS_SCHEMA_KYLIN_NM)) { +// QGSettings *gsetting = new QGSettings(GSETTINGS_SCHEMA_KYLIN_NM); +// if (gsetting->get(KEY_WIRELESS_SWITCH).toBool() != enable) { +// gsetting->set(KEY_WIRELESS_SWITCH, enable); +// } +// delete gsetting; +// gsetting = nullptr; +// } else { +// qDebug()<<"isSchemaInstalled false"; +// } + parent()->setWirelessSwitchEnable(enable); +} + +//启用/禁用网卡 +void DbusAdaptor::setDeviceEnable(QString devName, bool enable) +{ + parent()->setWiredDeviceEnable(devName, enable); + saveDeviceEnableState(devName, enable); +} + +//设置默认网卡 +//void DbusAdaptor::setDefaultWiredDevice(QString deviceName) +//{ +// if (!checkDeviceExist(WIRED, deviceName)) { +// return; +// } +// setDefaultDevice(WIRED, deviceName); +// parent()->setWiredDefaultDevice(deviceName); +// return; +//} + +//QString DbusAdaptor::getDefaultWiredDevice() +//{ +// QSettings * m_settings = new QSettings(CONFIG_FILE_PATH, QSettings::IniFormat); +// m_settings->beginGroup("DEFAULTCARD"); +// QString key("wired"); +// QString deviceName = m_settings->value(key, "").toString(); +// m_settings->endGroup(); +// delete m_settings; +// m_settings = nullptr; +// return deviceName; +//} + +//void DbusAdaptor::setDefaultWirelessDevice(QString deviceName) +//{ +// if (!checkDeviceExist(WIRED, deviceName)) { +// return; +// } +// setDefaultDevice(WIRELESS, deviceName); +// parent()->setWirelessDefaultDevice(deviceName); +// return; +//} + +//QString DbusAdaptor::getDefaultWirelessDevice() +//{ +// QSettings * m_settings = new QSettings(CONFIG_FILE_PATH, QSettings::IniFormat); +// m_settings->beginGroup("DEFAULTCARD"); +// QString key("wireless"); +// QString deviceName = m_settings->value(key, "").toString(); +// m_settings->endGroup(); +// delete m_settings; +// m_settings = nullptr; +// return deviceName; +//} + +//连接 根据网卡类型 参数1 0:lan 1:wlan 参数3 为ssid/uuid +void DbusAdaptor::activateConnect(int type, QString devName, QString ssid) +{ + if (type == WIRED) { + parent()->activateWired(devName,ssid); + } else if (type == WIRELESS) { + parent()->activateWireless(devName,ssid); + } else { + qDebug() << "[DbusAdaptor] activateConnect type is invalid"; + } +} + +//断开连接 根据网卡类型 参数1 0:lan 1:wlan 参数3 为ssid/uuid +void DbusAdaptor::deActivateConnect(int type, QString devName, QString ssid) +{ + if (type == WIRED) { + qDebug() << "deactivateWired"; + parent()->deactivateWired(devName,ssid); + } else if (type == WIRELESS) { + parent()->deactivateWireless(devName,ssid); + } else { + qDebug() << "[DbusAdaptor] deactivateConnect type is invalid"; + } +} + +//获取设备列表和启用/禁用状态 +QMap DbusAdaptor::getDeviceListAndEnabled(int devType) +{ + QMap map; + map.clear(); + getDeviceEnableState(devType, map); + return map; +} + +//获取无线设备能力 +QMap DbusAdaptor::getWirelessDeviceCap() +{ + QMap map; + parent()->getWirelessDeviceCap(map); + return map; +} + +//唤起属性页 根据网卡类型 参数2 为ssid/uuid +void DbusAdaptor::showPropertyWidget(QString devName, QString ssid) +{ + qDebug() << "showPropertyWidget"; + parent()->showPropertyWidget(devName,ssid); +} + +//唤起新建有线连接界面 +void DbusAdaptor::showCreateWiredConnectWidget(QString devName) +{ + qDebug() << "showCreateWiredConnectWidget"; + parent()->showCreateWiredConnectWidget(devName); +} + +//开启热点 +void DbusAdaptor::activeWirelessAp(const QString apName, const QString apPassword, const QString band, const QString apDevice) +{ + parent()->activeWirelessAp(apName, apPassword, band, apDevice); +} + +//断开热点 +void DbusAdaptor::deactiveWirelessAp(const QString apName, const QString uuid) +{ + parent()->deactiveWirelessAp(apName, uuid); +} + +//获取热点 +QStringList DbusAdaptor::getStoredApInfo() +{ + QStringList list; + list.clear(); + parent()->getStoredApInfo(list); + return list; +} + +QStringList DbusAdaptor::getApInfoBySsid(QString devName, QString ssid) +{ + QStringList list; + list.clear(); + parent()->getApInfoBySsid(devName, ssid, list); + return list; +} + +void DbusAdaptor::showKylinNM(int type) +{ + parent()->onShowMainWindow(type); +} + +//扫描 +void DbusAdaptor::reScan() +{ + parent()->rescan(); +} + +void DbusAdaptor::keyRingInit() +{ + parent()->keyRingInit(); +} + +void DbusAdaptor::keyRingClear() +{ + parent()->keyRingClear(); +} diff --git a/src/backend/dbusadaptor.h b/src/backend/dbusadaptor.h new file mode 100644 index 00000000..439851f9 --- /dev/null +++ b/src/backend/dbusadaptor.h @@ -0,0 +1,120 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp com.kylin.weather.xml -a dbusadaptor -c DbusAdaptor -l MainWindow + * + * qdbusxml2cpp is Copyright (C) 2015 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#ifndef DBUSADAPTOR_H +#define DBUSADAPTOR_H + +#include +#include +#include + +#include "tabpage.h" +#include "../dbus-interface/kylinnetworkdeviceresource.h" +QT_BEGIN_NAMESPACE +class QByteArray; +//template class QList; +template class QMap; +class QString; +class QStringList; +class QVariant; +template class QVector; +QT_END_NAMESPACE + +/* + * Adaptor class for interface com.kylin.weather + */ + +#include "mainwindow.h" + +class DbusAdaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.kylin.network") +public: + DbusAdaptor(MainWindow *parent); + virtual ~DbusAdaptor(); + + inline MainWindow *parent() const + { return static_cast(QObject::parent()); } + +public: // PROPERTIES +public Q_SLOTS: // METHODS + //无线列表 + QMap > getWirelessList(); + //有线列表 + QMap> getWiredList(); + //有线总开关 + Q_NOREPLY void setWiredSwitchEnable(bool enable); + //无线总开关 + Q_NOREPLY void setWirelessSwitchEnable(bool enable); + //有线网卡开关 + Q_NOREPLY void setDeviceEnable(QString devName, bool enable); + //设置默认网卡 +// Q_NOREPLY void setDefaultWiredDevice(QString deviceName); +// QString getDefaultWiredDevice(); +// Q_NOREPLY void setDefaultWirelessDevice(QString deviceName); +// QString getDefaultWirelessDevice(); + //连接 根据网卡类型 参数1 0:lan 1:wlan 参数3 为ssid/uuid + Q_NOREPLY void activateConnect(int type, QString devName, QString ssid); + //断开连接 根据网卡类型 参数1 0:lan 1:wlan 参数3 为ssid/uuid + Q_NOREPLY void deActivateConnect(int type, QString devName, QString ssid); + //获取设备列表和启用/禁用状态 + QMap getDeviceListAndEnabled(int devType); + //获取无线设备能力 + QMap getWirelessDeviceCap(); + //唤起属性页 根据网卡类型 参数2 为ssid/uuid + Q_NOREPLY void showPropertyWidget(QString devName, QString ssid); + //唤起新建有线连接界面 + Q_NOREPLY void showCreateWiredConnectWidget(QString devName); + //开启热点 + void activeWirelessAp(const QString apName, const QString apPassword, const QString band, const QString apDevice); + //断开热点 + void deactiveWirelessAp(const QString apName, const QString uuid); + //获取热点 + QStringList getStoredApInfo(); + QStringList getApInfoBySsid(QString devName, QString ssid); + //wifi扫描 + void reScan(); + //keyring + void keyRingInit(); + void keyRingClear(); + //just show + void showKylinNM(int type); +Q_SIGNALS: // SIGNALS +// void wirelessActivating(QString devName, QString ssid); +// void wiredActivating(QString devName, QString ssid); + void lanAdd(QString devName, QStringList info); + void lanRemove(QString dbusPath); + void lanUpdate(QString devName, QStringList info); + void wlanAdd(QString devName, QStringList info); + void wlanRemove(QString devName,QString ssid); + void wlanactiveConnectionStateChanged(QString devName, QString ssid, QString uuid, int status); + void lanActiveConnectionStateChanged(QString devName, QString uuid, int status); + //仅失败,若成功直接发listUpdate + void activateFailed(QString errorMessage); + void deactivateFailed(QString errorMessage); + //设备插拔 + void deviceStatusChanged(); + void deviceNameChanged(QString oldName, QString newName, int type); + //热点断开 + void hotspotDeactivated(QString devName, QString ssid); + //热点连接 + void hotspotActivated(QString devName, QString ssid, QString uuid); + + //信号强度变化 + void signalStrengthChange(QString devName, QString ssid, int strength); + //安全性变化 + void secuTypeChange(QString devName, QString ssid, QString secuType); + //列表排序 + void timeToUpdate(); +}; + +#endif diff --git a/src/backend/hotspot/dlghotspotcreate.cpp b/src/backend/hotspot/dlghotspotcreate.cpp new file mode 100644 index 00000000..afeb5b9d --- /dev/null +++ b/src/backend/hotspot/dlghotspotcreate.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * 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, 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 setupUi(this); + + this->setWindowFlags(Qt::FramelessWindowHint); + this->setStyleSheet("background-color:white;"); + + ui->lbLeftup->setStyleSheet("QLabel{background-color:#266ab5;}"); + ui->lbLeftupIcon->setStyleSheet("QLabel{background-image:url(:/res/h/no-pwd-wifi.png);background-color:transparent;}"); + ui->lbLeftupTitle->setStyleSheet("QLabel{font-size:12px;color:#ffffff;background-color:transparent;}"); + ui->btnCancel->setStyleSheet("QPushButton{border:1px solid #aaaaaa;background-color:#f5f5f5;}" + "QPushButton:Hover{border:2px solid #629ee8;background-color:#eeeeee;}" + "QPushButton:Pressed{border:1px solid #aaaaaa;background-color:#d8d8d8;}"); + ui->btnOk->setStyleSheet("QPushButton{border:1px solid #aaaaaa;background-color:#f5f5f5;}" + "QPushButton:Hover{border:2px solid #629ee8;background-color:#eeeeee;}" + "QPushButton:Pressed{border:1px solid #aaaaaa;background-color:#d8d8d8;}"); + ui->checkBoxPwd->setStyleSheet("QCheckBox::indicator {width: 18px; height: 9px;}" + "QCheckBox::indicator:checked {image: url(:/res/h/show-pwd.png);}" + "QCheckBox::indicator:unchecked {image: url(:/res/h/hide-pwd.png);}"); + + ui->lbLeftupTitle->setText(tr("Create Hotspot")); //创建个人热点 + ui->lbNetName->setText(tr("Network name")); //网络名称: + ui->lbSecurity->setText(tr("WLAN security")); //WLAN 安全性: + ui->lbPassword->setText(tr("Password")); //密码: + ui->btnCancel->setText(tr("Cancel")); //取消 + ui->btnOk->setText(tr("Ok")); //确定 + ui->btnOk->setEnabled(false); + + ui->cbxSecurity->addItem(tr("None")); //无 + ui->cbxSecurity->addItem(tr("WPA and WPA2 Personal")); //WPA 及 WPA2 个人 + ui->cbxSecurity->setCurrentIndex(1); + connect(ui->cbxSecurity,SIGNAL(currentIndexChanged(QString)),this,SLOT(changeDialog())); +} + +DlgHotspotCreate::~DlgHotspotCreate() +{ + delete ui; +} + +void DlgHotspotCreate::mousePressEvent(QMouseEvent *event){ + if(event->button() == Qt::LeftButton){ + this->isPress = true; + this->winPos = this->pos(); + this->dragPos = event->globalPos(); + event->accept(); + } +} +void DlgHotspotCreate::mouseReleaseEvent(QMouseEvent *event){ + this->isPress = false; + this->setWindowOpacity(1); +} +void DlgHotspotCreate::mouseMoveEvent(QMouseEvent *event){ + if(this->isPress){ + this->move(this->winPos - (this->dragPos - event->globalPos())); + this->setWindowOpacity(0.9); + event->accept(); + } +} + +void DlgHotspotCreate::on_btnCancel_clicked() +{ + this->close(); + emit btnHotspotState(); +} + +void DlgHotspotCreate::on_btnOk_clicked() +{ + //nmcli device wifi hotspot [ifname ifname] [con-name name] [ssid SSID] [band {a | bg}] [channel channel] [password password] + //example: nmcli device wifi hotspot ifname wlan0 con-name MyHostspot ssid MyHostspotSSID password 12345678 + QString str; + if(ui->cbxSecurity->currentIndex() == 0 ){ + str = "nmcli device wifi hotspot ifname '" + wirelessCardName + "' con-name '" + ui->leNetName->text() + "' ssid '" + ui->leNetName->text() + "' SSID"; + }else{ + str = "nmcli device wifi hotspot ifname '" + wirelessCardName + "' con-name '" + ui->leNetName->text() + "' ssid '" + ui->leNetName->text() + "' password '" + ui->lePassword->text() + "'"; + } + Utils::m_system(str.toUtf8().data()); + + this->close(); + emit updateHotspotList(); +} + +void DlgHotspotCreate::on_checkBoxPwd_stateChanged(int arg1) +{ + if (arg1 == 0) { + ui->lePassword ->setEchoMode(QLineEdit::Password); + } else { + ui->lePassword->setEchoMode(QLineEdit::Normal); + } +} + +void DlgHotspotCreate::on_leNetName_textEdited(const QString &arg1) +{ + if(ui->cbxSecurity->currentIndex() == 0 ){ + if (ui->leNetName->text() == ""){ + ui->btnOk->setEnabled(false); + } else { + ui->btnOk->setEnabled(true); + } + }else{ + if (ui->leNetName->text() == "" || ui->lePassword->text().size() < 5){ + ui->btnOk->setEnabled(false); + } else { + ui->btnOk->setEnabled(true); + } + } +} + +void DlgHotspotCreate::on_lePassword_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == "" || ui->lePassword->text().size() < 5){ + ui->btnOk->setEnabled(false); + } else { + ui->btnOk->setEnabled(true); + } +} + +void DlgHotspotCreate::changeDialog() +{ + if(ui->cbxSecurity->currentIndex()==0){ + ui->lbPassword->setEnabled(false); + ui->lePassword->setEnabled(false); + ui->checkBoxPwd->setEnabled(false); + } else { + ui->lbPassword->setEnabled(true); + ui->lePassword->setEnabled(true); + ui->checkBoxPwd->setEnabled(true); + } +} diff --git a/src/backend/hotspot/dlghotspotcreate.h b/src/backend/hotspot/dlghotspotcreate.h new file mode 100644 index 00000000..ee0ec0d2 --- /dev/null +++ b/src/backend/hotspot/dlghotspotcreate.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * 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, 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 +#include +#include + +namespace Ui { +class DlgHotspotCreate; +} + +class DlgHotspotCreate : public QDialog +{ + Q_OBJECT + +public: + explicit DlgHotspotCreate(QString wiFiCardName, QWidget *parent = nullptr); + ~DlgHotspotCreate(); + +public slots: + void changeDialog(); + +private slots: + void on_btnCancel_clicked(); + + void on_btnOk_clicked(); + + void on_checkBoxPwd_stateChanged(int arg1); + + void on_leNetName_textEdited(const QString &arg1); + + void on_lePassword_textEdited(const QString &arg1); + +private: + Ui::DlgHotspotCreate *ui; + + QString wirelessCardName; + + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + bool isPress; + QPoint winPos; + QPoint dragPos; + +signals: + void updateHotspotList(); + void btnHotspotState(); +}; + +#endif // DLGHOTSPOTCREATE_H diff --git a/src/backend/hotspot/dlghotspotcreate.ui b/src/backend/hotspot/dlghotspotcreate.ui new file mode 100644 index 00000000..989108f6 --- /dev/null +++ b/src/backend/hotspot/dlghotspotcreate.ui @@ -0,0 +1,169 @@ + + + DlgHotspotCreate + + + + 0 + 0 + 432 + 250 + + + + Dialog + + + + + 0 + 0 + 120 + 32 + + + + + + + + + + 9 + 9 + 16 + 16 + + + + + + + + + + 34 + 6 + 80 + 20 + + + + + + + + + + 215 + 210 + 90 + 30 + + + + + + + + + + 315 + 210 + 90 + 30 + + + + + + + + + + 76 + 60 + 90 + 20 + + + + + + + + + + 175 + 55 + 200 + 32 + + + + + + + 76 + 105 + 90 + 20 + + + + + + + + + + 175 + 100 + 200 + 32 + + + + + + + 76 + 150 + 90 + 20 + + + + + + + + + + 175 + 145 + 200 + 32 + + + + QLineEdit::Password + + + + + + 350 + 157 + 18 + 9 + + + + + + + + + + diff --git a/src/backend/hotspot/hotspot.pri b/src/backend/hotspot/hotspot.pri new file mode 100644 index 00000000..76750347 --- /dev/null +++ b/src/backend/hotspot/hotspot.pri @@ -0,0 +1,11 @@ +INCLUDEPATH += $$PWD + +FORMS += \ + $$PWD/dlghotspotcreate.ui + +HEADERS += \ + $$PWD/dlghotspotcreate.h + +SOURCES += \ + $$PWD/dlghotspotcreate.cpp + diff --git a/src/backend/kylinarping.h b/src/backend/kylinarping.h new file mode 100644 index 00000000..79346955 --- /dev/null +++ b/src/backend/kylinarping.h @@ -0,0 +1,101 @@ +#ifndef KYLINARPING_H +#define KYLINARPING_H + +#include +#include +#include + +static cap_flag_value_t cap_raw = CAP_CLEAR; +static const cap_value_t caps[] = { CAP_NET_RAW }; + +static void limit_capabilities() +{ + cap_t cap_p; + + cap_p = cap_get_proc(); + if (!cap_p) { + qWarning()<<"cap_get_proc failed."; + } + + cap_get_flag(cap_p, CAP_NET_RAW, CAP_PERMITTED, &cap_raw); + + if (cap_raw != CAP_CLEAR) { + if (cap_clear(cap_p) < 0) { + qWarning()<<"cap clear failed"< +#include +#include + +#define FINAL_PACKS 2 + +__attribute__((const)) static inline size_t sll_len(const size_t halen) +{ + struct sockaddr_ll unused; + const size_t len = offsetof(struct sockaddr_ll, sll_addr) + halen; + + if (len < sizeof(unused)) + return sizeof(unused); + + return len; +} + + +KyIpv4Arping::KyIpv4Arping(QString ifaceName, QString ipAddress, int retryCount, int timeout, QObject *parent) : QObject(parent) +{ + m_ifaceName = ifaceName; + m_ipv4Address = ipAddress; + m_retryCount = retryCount; + m_timeout = timeout; + + memset(&m_srcAddress, 0, sizeof(m_srcAddress)); +} + +KyIpv4Arping::~KyIpv4Arping() +{ + +} + +void KyIpv4Arping::monoGetTime (struct timespec *ts) +{ +#ifdef CLOCK_MONOTONIC + if (clock_gettime (CLOCK_MONOTONIC, ts)) +#endif + { + static long freq = 0; + if (freq == 0) + freq = sysconf (_SC_CLK_TCK); + + struct tms dummy; + clock_t t = times (&dummy); + ts->tv_sec = t / freq; + ts->tv_nsec = (t % freq) * (1000000000 / freq); + } +} + +void KyIpv4Arping::saveMacAddress(const uint8_t *ptr, size_t len) +{ + int index; + char macAddress[64] = {0}; + + for (index = 0; index < len; index++) { + snprintf(&macAddress[strlen(macAddress)], sizeof(macAddress) - strlen(macAddress), "%02X", ptr[index]); + if (index != len - 1) { + snprintf(&macAddress[strlen(macAddress)], sizeof(macAddress) - strlen(macAddress), "%s", ":"); + } + } + + m_conflictMac = QString(macAddress); + return ; +} + +void KyIpv4Arping::setConflictFlag(bool isConflict) +{ + m_ipConflict = isConflict; +} + +int KyIpv4Arping::sendIpv4Packet() +{ + int err; + unsigned char buf[256]; + struct arphdr *ah = (struct arphdr *)buf; + unsigned char *p = (unsigned char *)(ah + 1); + struct sockaddr_ll *p_me = (struct sockaddr_ll *)&(m_me); + struct sockaddr_ll *p_he = (struct sockaddr_ll *)&(m_he); + + ah->ar_hrd = htons(p_me->sll_hatype); + if (ah->ar_hrd == htons(ARPHRD_FDDI)) + ah->ar_hrd = htons(ARPHRD_ETHER); + ah->ar_pro = htons(ETH_P_IP); + ah->ar_hln = p_me->sll_halen; + ah->ar_pln = 4; + ah->ar_op = htons(ARPOP_REQUEST); + + memcpy(p, &p_me->sll_addr, ah->ar_hln); + p += p_me->sll_halen; + + qWarning()<<"[KyIpv4Arping]" <<"m_src address:" << inet_ntoa(m_srcAddress); + memcpy(p, &m_srcAddress, 4); + p += 4; + + memcpy(p, &p_he->sll_addr, ah->ar_hln); + p += ah->ar_hln; + + memcpy(p, &m_destAddress, 4); + p += 4; + + err = sendto(m_ipv4Socket, buf, p - buf, 0, (struct sockaddr *)p_he, sll_len(ah->ar_hln)); + + return err; +} + +int KyIpv4Arping::ipv4PacketProcess(unsigned char *buf, ssize_t len, struct sockaddr_ll *from) +{ + struct arphdr *ah = (struct arphdr *)buf; + unsigned char *p = (unsigned char *)(ah + 1); + struct in_addr src_ip, dst_ip; + + /* Filter out wild packets */ + if (from->sll_pkttype != PACKET_HOST && + from->sll_pkttype != PACKET_BROADCAST && + from->sll_pkttype != PACKET_MULTICAST) + return 0; + + /* Only these types are recognised */ + if (ah->ar_op != htons(ARPOP_REQUEST) && + ah->ar_op != htons(ARPOP_REPLY)) + return 0; + + /* ARPHRD check and this darned FDDI hack here :-( */ + if (ah->ar_hrd != htons(from->sll_hatype) && + (from->sll_hatype != ARPHRD_FDDI || ah->ar_hrd != htons(ARPHRD_ETHER))) + return 0; + + /* Protocol must be IP. */ + if (ah->ar_pro != htons(ETH_P_IP)) + return 0; + if (ah->ar_pln != 4) + return 0; + if (ah->ar_hln != ((struct sockaddr_ll *)&m_me)->sll_halen) + return 0; + + if (len < (ssize_t) sizeof(*ah) + 2 * (4 + ah->ar_hln)) + return 0; + + memcpy(&src_ip, p + ah->ar_hln, 4); + memcpy(&dst_ip, p + ah->ar_hln + 4 + ah->ar_hln, 4); + /* + * DAD packet was: + * src_ip = 0 (or some src) + * src_hw = ME + * dst_ip = tested address + * dst_hw = + * + * We fail, if receive request/reply with: + * src_ip = tested_address + * src_hw != ME + * if src_ip in request was not zero, check + * also that it matches to dst_ip, otherwise + * dst_ip/dst_hw do not matter. + */ + if (src_ip.s_addr != m_destAddress.s_addr) + return 0; + + if (memcmp(p, ((struct sockaddr_ll *)&m_me)->sll_addr, + ((struct sockaddr_ll *)&m_me)->sll_halen) == 0) + return 0; + + saveMacAddress(p, ah->ar_hln); + setConflictFlag(true); + + return FINAL_PACKS; +} + +int KyIpv4Arping::ipv4EventLoop() +{ + int rc = -1; + int ret; + int index; + int exit_loop = 0; + ssize_t bytes; + + int tfd; + struct pollfd pfds[POLLFD_COUNT]; + + struct itimerspec timerfd_vals; + timerfd_vals.it_interval.tv_sec = m_timeout, + timerfd_vals.it_interval.tv_nsec = 0, + timerfd_vals.it_value.tv_sec = m_timeout, + timerfd_vals.it_value.tv_nsec = 0; + + uint64_t exp; + uint64_t total_expires = 1; + + unsigned char packet[4096]; + struct sockaddr_storage from = { 0 }; + socklen_t addr_len = sizeof(from); + + /* timerfd */ + tfd = timerfd_create(CLOCK_MONOTONIC, 0); + if (tfd == -1) { + qWarning()<<"[KyIpv4Arping]" << "timerfd_create failed, errno" << errno; + return -1; + } + + if (timerfd_settime(tfd, 0, &timerfd_vals, NULL)) { + close(tfd); + qWarning()<<"[KyIpv4Arping]" << "timerfd_settime failed, errno" << errno; + return -1; + } + + pfds[POLLFD_TIMER].fd = tfd; + pfds[POLLFD_TIMER].events = POLLIN | POLLERR | POLLHUP; + + /* socket */ + pfds[POLLFD_SOCKET].fd = m_ipv4Socket; + pfds[POLLFD_SOCKET].events = POLLIN | POLLERR | POLLHUP; + sendIpv4Packet(); + + while (!exit_loop) { + ret = poll(pfds, POLLFD_COUNT, -1); + if (ret <= 0) { + if (errno == EAGAIN) { + continue; + } + + if (errno) { + qWarning()<<"[KyIpv4Arping]" <<"poll failed, errno" << errno; + } + + exit_loop = 1; + continue; + } + + for (index = 0; index < POLLFD_COUNT; index++) { + if (pfds[index].revents == 0) { + continue; + } + + switch (index) { + case POLLFD_TIMER: + bytes = read(tfd, &exp, sizeof(uint64_t)); + if (bytes != sizeof(uint64_t)) { + qWarning() <<"[KyIpv4Arping]" << "could not read timerfd"; + continue; + } + + total_expires += exp; + if (0 < m_retryCount && (uint64_t)m_retryCount < total_expires) { + exit_loop = 1; + rc = 0; + continue; + } + + sendIpv4Packet(); + break; + case POLLFD_SOCKET: + bytes = recvfrom(m_ipv4Socket, packet, sizeof(packet), 0, + (struct sockaddr *)&from, &addr_len); + if (bytes < 0) { + qWarning()<<"[KyIpv4Arping]" << "recvfrom function failed, errno" << errno; + continue; + } + if (ipv4PacketProcess(packet, bytes, (struct sockaddr_ll *)&from) == FINAL_PACKS) { + exit_loop = 1; + rc = 0; + } + break; + default: + qWarning()<<"[KyIpv4Arping]" <<"the fd index is undefine" << index; + break; + } + } + } + + close(tfd); + freeifaddrs(m_ifa0); + + return rc; +} + +int KyIpv4Arping::checkIfflags(unsigned int ifflags) +{ + if (!(ifflags & IFF_UP)) { + qWarning()<<"[KyIpv4Arping]" <<"the iface" << m_ifaceName <<" is down."; + return -1; + } + + if (ifflags & (IFF_NOARP | IFF_LOOPBACK)) { + qWarning()<<"[KyIpv4Arping]" << "Interface" << m_ifaceName << "is not ARPable."; + return -1; + } + + return 0; +} + + +int KyIpv4Arping::checkDevice() +{ + int rc; + struct ifaddrs *ifa; + int n = 0; + + rc = getifaddrs(&m_ifa0); + if (rc < 0) { + qWarning()<<"[KyIpv4Arping]" <<"get iface address failed, erron"<< errno; + return -errno; + } + + for (ifa = m_ifa0; ifa; ifa = ifa->ifa_next) { + if (!ifa->ifa_addr) { + continue; + } + + if (ifa->ifa_addr->sa_family != AF_PACKET) { + continue; + } + + if (!m_ifaceName.isEmpty() + && (NULL != ifa->ifa_name) + && strcmp(ifa->ifa_name, m_ifaceName.toUtf8())) { + continue; + } + + if (checkIfflags(ifa->ifa_flags) < 0) { + continue; + } + + if (!((struct sockaddr_ll *)ifa->ifa_addr)->sll_halen) { + continue; + } + + if (!ifa->ifa_broadaddr) { + continue; + } + + m_ifa = ifa; + + if (n++) + break; + } + + if (n == 1 && m_ifa) { + m_ifindex = if_nametoindex(m_ifa->ifa_name); + if (!m_ifindex) { + qWarning()<<"[KyIpv4Arping]" <<"if_nametoindex is invalid"; + freeifaddrs(m_ifa0); + return -1; + } + m_ifaceName = m_ifa->ifa_name; + + return 0; + } + + freeifaddrs(m_ifa0); + return -1; +} + +void KyIpv4Arping::findBroadcastAddress() +{ + struct sockaddr_ll *he = (struct sockaddr_ll *)&(m_he); + + if (m_ifa) { + struct sockaddr_ll *sll = + (struct sockaddr_ll *)m_ifa->ifa_broadaddr; + + if (sll->sll_halen == he->sll_halen) { + memcpy(he->sll_addr, sll->sll_addr, he->sll_halen); + return; + } + } + + qWarning()<<"[KyIpv4Arping]" <<"using default broadcast address."; + + memset(he->sll_addr, -1, he->sll_halen); + + return; +} + +int KyIpv4Arping::ipv4ConflictCheck() +{ + limit_capabilities(); + + int ret = checkDevice(); + if (ret < 0) { + qWarning()<<"[KyIpv4Arping]"<<"the device is invalid" << m_ifaceName; + return -1; + } + + enable_capability_raw(); + m_ipv4Socket = socket(PF_PACKET, SOCK_DGRAM, 0); + disable_capability_raw(); + if (m_ipv4Socket < 0) { + qWarning()<<"[KyIpv4Arping]" << "create ipv4 socket failed, errno" << errno; + return -1; + } + + inet_aton(m_ipv4Address.toUtf8(), &m_destAddress); + m_destAddressFamily = AF_INET; + + ((struct sockaddr_ll *)&m_me)->sll_family = AF_PACKET; + ((struct sockaddr_ll *)&m_me)->sll_ifindex = m_ifindex; + ((struct sockaddr_ll *)&m_me)->sll_protocol = htons(ETH_P_ARP); + + ret = bind(m_ipv4Socket, (struct sockaddr *)&m_me, sizeof(m_me)); + if (ret < 0) { + qWarning()<<"[KyIpv4Arping]" <<"ipv4 socket bind failed, errno"<< errno; + close(m_ipv4Socket); + return -1; + } + + socklen_t alen = sizeof(m_me); + ret = getsockname(m_ipv4Socket, (struct sockaddr *)&m_me, &alen); + if (ret < 0) { + qWarning()<<"[KyIpv4Arping]" <<"ipv4 get socket name failed, errno" << errno; + close(m_ipv4Socket); + return -1; + } + + if (((struct sockaddr_ll *)&m_me)->sll_halen == 0) { + qWarning()<<"[KyIpv4Arping]" <<"the iface"<< m_ifaceName <<" is not suitable for arp"; + close(m_ipv4Socket); + return -1; + } + + m_he = m_me; + + findBroadcastAddress(); + + drop_capabilities(); + + ret = ipv4EventLoop(); + close(m_ipv4Socket); + + return ret; +} diff --git a/src/backend/kylinipv4arping.h b/src/backend/kylinipv4arping.h new file mode 100644 index 00000000..1cb8ea36 --- /dev/null +++ b/src/backend/kylinipv4arping.h @@ -0,0 +1,88 @@ +#ifndef KYLIN_IPV4_ARPING +#define KYLIN_IPV4_ARPING + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "kylinarping.h" + +#include +#include +#include + +enum { + POLLFD_TIMER = 0, + POLLFD_SOCKET, + POLLFD_COUNT +}; + +class KyIpv4Arping : public QObject +{ + Q_OBJECT +public: + explicit KyIpv4Arping(QString ifaceName, QString ipAddress, int retryCount=3, int timeout=1, QObject *parent = nullptr); + ~KyIpv4Arping(); + +public: + bool ipv4IsConflict() { + return m_ipConflict; + } + + QString getMacAddress() { + return m_conflictMac; + } + + int ipv4ConflictCheck(); + +private: + void monoGetTime(struct timespec *ts); + void saveMacAddress(const uint8_t *ptr, size_t len); + void findBroadcastAddress(); + int checkDevice(); + int checkIfflags(unsigned int ifflags); + + int sendIpv4Packet(); + int ipv4EventLoop(); + int ipv4PacketProcess(unsigned char *buf, ssize_t len, struct sockaddr_ll *from); + + void setConflictFlag(bool isConflict); + +private: + struct in_addr m_srcAddress; + struct in_addr m_destAddress; + int m_destAddressFamily; + + struct sockaddr_storage m_me; + struct sockaddr_storage m_he; + int m_ipv4Socket = 0; + + QString m_ifaceName; + int m_ifindex; + struct ifaddrs *m_ifa; + struct ifaddrs *m_ifa0; + + QString m_ipv4Address; + int m_retryCount; + int m_timeout; + + bool m_ipConflict = false; + QString m_conflictMac = nullptr; +}; + +#endif diff --git a/src/backend/kylinipv6arping.cpp b/src/backend/kylinipv6arping.cpp new file mode 100644 index 00000000..79d2ee12 --- /dev/null +++ b/src/backend/kylinipv6arping.cpp @@ -0,0 +1,405 @@ +#include "kylinipv6arping.h" + +#include +#include +#include +#include "kylinarping.h" + +KyIpv6Arping::KyIpv6Arping(QString ifaceName, QString ipAddress, int retryCount, int timeout, QObject *parent) : QObject(parent) +{ + m_ifaceName = ifaceName; + m_ipv6Address = ipAddress; + m_retryCount = retryCount; + m_timeoutMs = timeout; + + m_ipv6Conflict = false; +} + +KyIpv6Arping::~KyIpv6Arping() +{ + +} + +void KyIpv6Arping::monoGetTime (struct timespec *ts) +{ +#ifdef CLOCK_MONOTONIC + if (clock_gettime (CLOCK_MONOTONIC, ts)) +#endif + { + static long freq = 0; + if (freq == 0) + freq = sysconf (_SC_CLK_TCK); + + struct tms dummy; + clock_t t = times (&dummy); + ts->tv_sec = t / freq; + ts->tv_nsec = (t % freq) * (1000000000 / freq); + } +} + +int KyIpv6Arping::getLocalMacAddress(const char *ifname, unsigned char *addr) +{ +# ifdef SIOCGIFHWADDR + struct ifreq req; + memset (&req, 0, sizeof (req)); + + if (((unsigned)strlen (ifname)) >= (unsigned)IFNAMSIZ) { + return -1; /* buffer overflow = local root */ + } + + strcpy (req.ifr_name, ifname); + + int fd = socket (AF_INET6, SOCK_DGRAM, 0); + if (fd == -1) { + return -1; + } + + if (ioctl (fd, SIOCGIFHWADDR, &req)) { + qWarning()<<"[KyIpv6Arping]"<<"get local mac address failed, errno" << errno; + close (fd); + return -1; + } + close (fd); + + memcpy (addr, req.ifr_hwaddr.sa_data, 6); + return 0; +# else + /* No SIOCGIFHWADDR, which seems Linux specific. */ + struct ifaddrs *ifa = NULL; + struct ifaddrs *ifp = NULL; + getifaddrs(&ifa); + ifp = ifa; /* preserve the address of ifa to free memory later */ + while (ifp != NULL) { + if (ifp->ifa_addr->sa_family == AF_LINK && strcmp(ifp->ifa_name, ifname) == 0) { + const struct sockaddr_dl* sdl = (const struct sockaddr_dl*) ifp->ifa_addr; + memcpy(addr, sdl->sdl_data + sdl->sdl_nlen, 6); + freeifaddrs(ifa); + return 0; + } + ifp = ifp->ifa_next; + } + freeifaddrs(ifa); + return -1; +# endif +} + +int KyIpv6Arping::getIpv6ByName(struct sockaddr_in6 *addr) +{ + struct addrinfo hints, *res; + memset (&hints, 0, sizeof (hints)); + hints.ai_family = PF_INET6; + hints.ai_socktype = SOCK_DGRAM; /* dummy */ + hints.ai_flags = 0; + + int val = getaddrinfo (m_ipv6Address.toUtf8(), NULL, &hints, &res); + if (val) { + qWarning()<<"[KyIpv6Arping]" << m_ipv6Address <<"get addrinfo failed, errno" << val; + return -1; + } + + memcpy (addr, res->ai_addr, sizeof (struct sockaddr_in6)); + freeaddrinfo (res); + + val = if_nametoindex (m_ifaceName.toUtf8()); + if (val == 0) { + qWarning()<<"[KyIpv6Arping]" <<"if_nametoindex failed, errno" << errno; + return -1; + } + addr->sin6_scope_id = val; + + return 0; +} + +int KyIpv6Arping::buildSolicitationPacket(solicit_packet *ns, struct sockaddr_in6 *tgt, const char *ifname) +{ + /* builds ICMPv6 Neighbor Solicitation packet */ + ns->hdr.nd_ns_type = ND_NEIGHBOR_SOLICIT; + ns->hdr.nd_ns_code = 0; + ns->hdr.nd_ns_cksum = 0; /* computed by the kernel */ + ns->hdr.nd_ns_reserved = 0; + memcpy (&ns->hdr.nd_ns_target, &tgt->sin6_addr, 16); + + /* determines actual multicast destination address */ + memcpy (&tgt->sin6_addr.s6_addr, "\xff\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x01\xff", 13); + + /* gets our own interface's link-layer address (MAC) */ + if (getLocalMacAddress (m_ifaceName.toUtf8().constData(), ns->hw_addr)) { + return sizeof (ns->hdr); + } + + ns->opt.nd_opt_type = ND_OPT_SOURCE_LINKADDR; + ns->opt.nd_opt_len = 1; /* 8 bytes */ + return sizeof (*ns); +} + +void KyIpv6Arping::saveMacAddress (const uint8_t *ptr, size_t len) +{ + int index; + char macAddress[64] = {0}; + + for (index = 0; index < len; index++) { + snprintf(&macAddress[strlen(macAddress)], sizeof(macAddress) - strlen(macAddress), "%02X", ptr[index]); + if (index != len - 1) { + snprintf(&macAddress[strlen(macAddress)], sizeof(macAddress) - strlen(macAddress), "%s", ":"); + } + } + + m_conflictMacAddress = QString(macAddress); + return ; +} + +int KyIpv6Arping::parseIpv6Packet(const uint8_t *buf, size_t len, const struct sockaddr_in6 *tgt) +{ + const struct nd_neighbor_advert *na = + (const struct nd_neighbor_advert *)buf; + const uint8_t *ptr; + + /* checks if the packet is a Neighbor Advertisement, and + * if the target IPv6 address is the right one */ + if ((len < sizeof (struct nd_neighbor_advert)) + || (na->nd_na_type != ND_NEIGHBOR_ADVERT) + || (na->nd_na_code != 0) + || memcmp (&na->nd_na_target, &tgt->sin6_addr, 16)) { + return -1; + } + len -= sizeof (struct nd_neighbor_advert); + + /* looks for Target Link-layer address option */ + ptr = buf + sizeof (struct nd_neighbor_advert); + + while (len >= 8) + { + uint16_t optlen; + + optlen = ((uint16_t)(ptr[1])) << 3; + if (optlen == 0) + break; /* invalid length */ + + if (len < optlen) /* length > remaining bytes */ + break; + len -= optlen; + + + /* skips unrecognized option */ + if (ptr[0] != ND_OPT_TARGET_LINKADDR) + { + ptr += optlen; + continue; + } + + /* Found! displays link-layer address */ + ptr += 2; + optlen -= 2; + + saveMacAddress (ptr, optlen); + setIpv6ConflictFlag(true); + return 0; + } + + return -1; +} + +int KyIpv6Arping::readIpv6Packet(void *buf, + size_t len, + int flags, + struct sockaddr_in6 *addr) +{ + char cbuf[CMSG_SPACE (sizeof (int))]; + + struct iovec iov = { + .iov_base = buf, + .iov_len = len + }; + + struct msghdr hdr = { + .msg_name = addr, + .msg_namelen = sizeof (*addr), + .msg_iov = &iov, + .msg_iovlen = 1, + .msg_control = cbuf, + .msg_controllen = sizeof (cbuf) + }; + + ssize_t val = recvmsg (m_ipv6Socket, &hdr, flags); + if (val == -1) { + return val; + } + + /* ensures the hop limit is 255 */ + for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (&hdr); + cmsg != NULL; cmsg = CMSG_NXTHDR (&hdr, cmsg)) { + if ((cmsg->cmsg_level == IPPROTO_IPV6) + && (cmsg->cmsg_type == IPV6_HOPLIMIT)) { + if (255 != *(int *)CMSG_DATA (cmsg)) { + // pretend to be a spurious wake-up + errno = EAGAIN; + return -1; + } + } + } + + return val; +} + +int KyIpv6Arping::reciveAndProcessIpv6Packet(const struct sockaddr_in6 *tgt, unsigned wait_ms) +{ + struct timespec end; + struct pollfd fds; + + /* computes deadline time */ + monoGetTime (&end); + div_t d; + d = div (wait_ms, 1000); + end.tv_sec = end.tv_sec + d.quot; + end.tv_nsec = end.tv_nsec + (d.rem * 1000000); + + /* receive loop */ + for (;;) + { + /* waits for reply until deadline */ + struct timespec now; + int val = 0; + + monoGetTime (&now); + if (end.tv_sec >= now.tv_sec) { + val = (end.tv_sec - now.tv_sec) * 1000 + + (int)((end.tv_nsec - now.tv_nsec) / 1000000); + if (val < 0) { + val = 0; + } + } + + fds.fd = m_ipv6Socket; + fds.events = POLLIN; + val = poll (&fds, 1, val); + if (val < 0) + break; + + if (val == 0) + return 0; + + /* receives an ICMPv6 packet */ + // TODO: use interface MTU as buffer size + uint8_t buf[1460]; + struct sockaddr_in6 addr; + + val = readIpv6Packet(buf, sizeof (buf), MSG_DONTWAIT, &addr); + if (val < 0) { + if (errno != EAGAIN) + qWarning()<<"[KyIpv6Arping]"<<"Receiving ICMPv6 packet failed"; + continue; + } + + /* ensures the response came through the right interface */ + if (addr.sin6_scope_id + && (addr.sin6_scope_id != tgt->sin6_scope_id)) + continue; + + if (parseIpv6Packet(buf, val, tgt) == 0) { + return 1 /* = responses */; + } + } + + return -1; /* error */ +} + + +int KyIpv6Arping::ipv6ConflictCheck() +{ + struct sockaddr_in6 tgt; + struct icmp6_filter filter; + int retry = 0; + + limit_capabilities(); + + enable_capability_raw(); + m_ipv6Socket = socket (PF_INET6, SOCK_RAW, IPPROTO_ICMPV6); + disable_capability_raw(); + if (m_ipv6Socket < 0) { + qDebug()<<"[KyIpv6Arping]" <<"create ipv6 socket failed:"; + return -1; + } + + fcntl (m_ipv6Socket, F_SETFD, FD_CLOEXEC); + + /* set ICMPv6 filter */ + ICMP6_FILTER_SETBLOCKALL (&filter); + ICMP6_FILTER_SETPASS (ND_NEIGHBOR_ADVERT, &filter); + + enable_capability_raw(); + setsockopt (m_ipv6Socket, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, sizeof (filter)); + + int soDontRoute = 1; + setsockopt (m_ipv6Socket, SOL_SOCKET, SO_DONTROUTE, &soDontRoute, sizeof(soDontRoute)); + + /* sets Hop-by-hop limit to 255 */ + int multicastHopLimit = 255; + setsockopt (m_ipv6Socket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, + &multicastHopLimit, sizeof (multicastHopLimit)); + + int unicastHops = 255; + setsockopt (m_ipv6Socket, IPPROTO_IPV6, IPV6_UNICAST_HOPS, + &unicastHops, sizeof (unicastHops)); + + int recvHopLimit = 1; + setsockopt(m_ipv6Socket, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, + &recvHopLimit, sizeof (recvHopLimit)); + + disable_capability_raw(); + + drop_capabilities(); + + /* resolves target's IPv6 address */ + int ret = getIpv6ByName(&tgt); + if (ret < 0) { + qWarning()<<"[KyIpv6Arping]"<<"get ipv6 by name failed."; + close (m_ipv6Socket); + return ret; + } + + solicit_packet packet; + struct sockaddr_in6 dst; + ssize_t plen; + + memcpy (&dst, &tgt, sizeof (dst)); + plen = buildSolicitationPacket(&packet, &dst, m_ifaceName.toUtf8().constData()); + if (plen == -1) { + qWarning()<<"[KyIpv6Arping]"<<"build solicit packet failed."; + close (m_ipv6Socket); + return -1; + } + + while (retry < m_retryCount) { + /* sends a Solitication */ + if (sendto (m_ipv6Socket, &packet, plen, MSG_DONTROUTE, + (const struct sockaddr *)&dst, + sizeof (dst)) != plen) { + qWarning()<<"[KyIpv6Arping]"<<"Sending ICMPv6 packet failed."; + close (m_ipv6Socket); + return -1; + } + + retry++; + + /* receives an Advertisement */ + ssize_t val = reciveAndProcessIpv6Packet(&tgt, m_timeoutMs); + if (val > 0) { + close (m_ipv6Socket); + return 0; + } else if (val == 0) { + continue; + } else { + close (m_ipv6Socket); + return -1; + } + } + + close(m_ipv6Socket); + + if (retry == m_retryCount) { + return 0; + } else { + return -2; + } +} diff --git a/src/backend/kylinipv6arping.h b/src/backend/kylinipv6arping.h new file mode 100644 index 00000000..7f92c8ee --- /dev/null +++ b/src/backend/kylinipv6arping.h @@ -0,0 +1,109 @@ +#ifndef KYLINIPV6ARPING_H +#define KYLINIPV6ARPING_H + +//#include + +#include +#include +#include /* div() */ +#include /* uint8_t */ +#include /* UINT_MAX */ +#include +#include + +#include /* EMFILE */ +#include +#include /* close() */ +#include /* clock_gettime() */ +#include /* poll() */ +#include +#include +#include + +//#include "gettime.h" + +#ifdef HAVE_GETOPT_H +# include +#endif + +#include /* getaddrinfo() */ +#include /* inet_ntop() */ +#include /* if_nametoindex() */ + +#include +#include + +#ifndef IPV6_RECVHOPLIMIT +/* Using obsolete RFC 2292 instead of RFC 3542 */ +# define IPV6_RECVHOPLIMIT IPV6_HOPLIMIT +#endif + +/* BSD-like systems define ND_RA_FLAG_HA instead of ND_RA_FLAG_HOME_AGENT */ +#ifndef ND_RA_FLAG_HOME_AGENT +# ifdef ND_RA_FLAG_HA +# define ND_RA_FLAG_HOME_AGENT ND_RA_FLAG_HA +# endif +#endif + +#ifndef AI_IDN +# define AI_IDN 0 +#endif + + +#include +#include +#include + +typedef struct +{ + struct nd_neighbor_solicit hdr; + struct nd_opt_hdr opt; + uint8_t hw_addr[6]; +} solicit_packet; + +class KyIpv6Arping: public QObject +{ + Q_OBJECT +public: + explicit KyIpv6Arping(QString ifaceName, QString ipAddress, int retryCount=3, int timeout=1000, QObject *parent = nullptr); + ~KyIpv6Arping(); + +public: + bool ipv6IsConflict() { + return m_ipv6Conflict; + } + + void setIpv6ConflictFlag(bool conflict) { + m_ipv6Conflict = conflict; + } + + QString getConflictMacAddress() { + return m_conflictMacAddress; + } + + int ipv6ConflictCheck(); + +private: + void monoGetTime (struct timespec *ts); + void saveMacAddress (const uint8_t *ptr, size_t len); + int getLocalMacAddress(const char *ifname, unsigned char *addr); + + int getIpv6ByName(struct sockaddr_in6 *addr); + int buildSolicitationPacket(solicit_packet *ns, struct sockaddr_in6 *tgt, const char *ifname); + int parseIpv6Packet(const uint8_t *buf, size_t len, const struct sockaddr_in6 *tgt); + int readIpv6Packet(void *buf, size_t len, int flags, struct sockaddr_in6 *addr); + int reciveAndProcessIpv6Packet(const struct sockaddr_in6 *tgt, unsigned wait_ms); + +private: + int m_ipv6Socket = 0; + + QString m_ifaceName; + QString m_ipv6Address; + int m_retryCount; + int m_timeoutMs; + + bool m_ipv6Conflict = false; + QString m_conflictMacAddress = nullptr; +}; + +#endif // KYLINIPV6ARPING_H diff --git a/src/backend/sysdbusregister.cpp b/src/backend/sysdbusregister.cpp new file mode 100644 index 00000000..fa1d5a38 --- /dev/null +++ b/src/backend/sysdbusregister.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * 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, 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 +#include +#include + +SysdbusRegister::SysdbusRegister() +{ +} + +SysdbusRegister::~SysdbusRegister() +{ +} + +void SysdbusRegister::systemRun(QString cmd){ + QProcess::execute(cmd); +} + +QStringList SysdbusRegister::getWifiInfo(QString wifiName) { + //返回名为wifiName的企业wifi的配置信息,包括eap,inner和用户列表 + QStringList wlist; + QString filename = "/usr/share/kylin-nm/wpaconn.conf"; + QFile file(filename); + if(!file.exists()) { + return wlist; + } + QSharedPointer autoSettings = QSharedPointer(new QSettings(filename, QSettings::IniFormat)); + wlist << autoSettings.get()->value("eap").toString(); + wlist << autoSettings.get()->value("inner").toString(); + int size = autoSettings.get()->beginReadArray(wifiName); + for (int i = 0; i < size; ++i) { + autoSettings.get()->setArrayIndex(i); + wlist << autoSettings.get()->value("user").toString(); + } + autoSettings.get()->endArray(); + return wlist; +} + +bool SysdbusRegister::appendWifiInfo(QString name, QString eap, QString inner, QString user) { + //向配置文件添加名为name的wifi配置,包括eap,inner和它的第一个用户 + QString filename = "/usr/share/kylin-nm/wpaconn.conf"; + QSharedPointer autoSettings = QSharedPointer(new QSettings(filename, QSettings::IniFormat)); + autoSettings.get()->beginGroup(name); + autoSettings.get()->setValue("eap", eap); + autoSettings.get()->setValue("inner", inner); + //以数组形式写入用户名 + autoSettings.get()->beginWriteArray(name); + autoSettings.get()->setArrayIndex(0); + autoSettings.get()->setValue("user", user); + autoSettings.get()->endArray(); + return true; +} + +bool SysdbusRegister::appendWifiUser(QString name, QString user) { + //向名为name的wifi用户列表添加名为user的用户名 + QString filename = "/usr/share/kylin-nm/wpaconn.conf"; + QSharedPointer autoSettings = QSharedPointer(new QSettings(filename, QSettings::IniFormat)); + autoSettings.get()->beginWriteArray(name); + autoSettings.get()->setArrayIndex(0); + //读到用户名列表长度并在队尾添加一个用户名 + int size = autoSettings.get()->beginReadArray(name); + autoSettings.get()->setArrayIndex(size); + autoSettings.get()->setValue("user", user); + autoSettings.get()->endArray(); + return true; +} diff --git a/src/backend/sysdbusregister.h b/src/backend/sysdbusregister.h new file mode 100644 index 00000000..942a54f3 --- /dev/null +++ b/src/backend/sysdbusregister.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * 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, 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 +#include +#include +#include +#include +#include +#include + +#include + +class SysdbusRegister : public QObject +{ + Q_OBJECT + + Q_CLASSINFO("D-Bus Interface", "com.kylin.NetworkManager.interface") + +public: + explicit SysdbusRegister(); + ~SysdbusRegister(); + +private: +// QString m_name; + +signals: +// Q_SCRIPTABLE void nameChanged(QString); +// Q_SCRIPTABLE void computerinfo(QString); + +public slots: + + Q_SCRIPTABLE void systemRun(QString cmd); + Q_SCRIPTABLE QStringList getWifiInfo(QString wifiName); + Q_SCRIPTABLE bool appendWifiInfo(QString name, QString eap, QString inner, QString user); + Q_SCRIPTABLE bool appendWifiUser(QString name, QString user); + +}; + +#endif // SYSDBUSREGISTER_H diff --git a/src/backend/utils.cpp b/src/backend/utils.cpp new file mode 100644 index 00000000..8c2959b0 --- /dev/null +++ b/src/backend/utils.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * 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, 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 +#include +#include +#include +#include +#include +#include +#include +#include + + +/////////////////////////////////////////////////////////////////////////////// +// The Utils class + +Utils::Utils(){} + +int Utils::m_system(char *cmd) +{ + int status = 0; + pid_t pid; + clock_t start,finish; + if ((pid = vfork()) <0) { + qDebug()<<"failed to create a subprocess by using vfork"; + status = -1; + } else if (pid==0) { + const char *new_argv[4]; + struct sigaction sa_cld; + sa_cld.sa_handler = SIG_DFL; + sa_cld.sa_flags = 0; + + // 在子进程中放开SIGINT信号 + sigemptyset(&sa_cld.sa_mask); + sigaction (SIGINT, &sa_cld, NULL); + sigaction (SIGQUIT, &sa_cld, NULL); + + new_argv[0] = "sh"; + new_argv[1] = "-c"; + new_argv[2] = cmd; + new_argv[3] = NULL; + + // execl("/bin/sh","sh","-c" ,cmd,(char *)0); + start = clock(); + if (execve("/bin/sh",(char *const *) new_argv, NULL) <0) { + qDebug()<<"failed to execve a shell command in function m_system"; + exit(1); + } else { + exit(0); + } + } else { + waitpid(pid,&status,0); + finish = clock(); + } + //double duration = (double)(finish-start)/CLOCKS_PER_SEC; + //qDebug()<<"It takes "< args; + args<<(tr("Kylin NM")) + <<((unsigned int) 0) + < +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* qt会将glib里的signals成员识别为宏,所以取消该宏 + * 后面如果用到signals时,使用Q_SIGNALS代替即可 + * +#ifdef signals +#undef signals +#endif + +extern "C" { +#include +#include +} + */ + + +/////////////////////////////////////////////////////////////////////////////// +// wifi property struct + typedef struct structWifiProperty{ + QString objectPath; + QString bssid; + int priority; +}structWifiProperty; + + +/////////////////////////////////////////////////////////////////////////////// +// The Utils class, used to do some assist function + +class Utils : public QObject +{ + Q_OBJECT +public: + Utils(); + + static int m_system(char *cmd); + +public slots: + void onRequestSendDesktopNotify(QString message); + +}; + + +/////////////////////////////////////////////////////////////////////////////// +// The UseQssFile class, set control style by using .qss file + +class UseQssFile +{ +public: + static void setStyle(const QString &style) + { + QString styleName = ":/qss/" + style; + + QFile qss(styleName); + qss.open(QFile::ReadOnly); + qApp->setStyleSheet(qss.readAll()); + qss.close(); + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// The NetworkSpeed class, get the network upload and download speed + +class NetworkSpeed : public QObject +{ + Q_OBJECT +public: + explicit NetworkSpeed(QObject *parent = nullptr); + + int getCurrentDownloadRates(char *netname,long int * save_rate,long int * tx_rate); //获取当前的流量,参数为将获取到的流量保 +}; + +#endif // UTILS_H diff --git a/src/backend/wifi-auth-thread.cpp b/src/backend/wifi-auth-thread.cpp new file mode 100644 index 00000000..3ad12ca0 --- /dev/null +++ b/src/backend/wifi-auth-thread.cpp @@ -0,0 +1,53 @@ +#include "wifi-auth-thread.h" + +#include + +WifiAuthThread::WifiAuthThread() +{ + //检查连接状态 + naManager = new QNetworkAccessManager(this); +// QString url=QString("http://nmcheck.gnome.org/check_network_status.txt"); + QString url=QString("http://connectivity-check.ubuntu.com/"); + request.setUrl(QUrl(url)); + naManager->get(request); + //qDebug()<<"-------------------Network state check!----------------------"; + connect(naManager,&QNetworkAccessManager::finished,this,[=](QNetworkReply* reply){ + _isReply=true; + QNetworkReply::NetworkError err = reply->error(); + //qDebug()<<"----------------NetworkReply error:----------------------"<readAll().isEmpty()) + _isConnect=false; + } + else + _isConnect=false; + }); +} + +WifiAuthThread::~WifiAuthThread() +{ + delete naManager; +} + +void WifiAuthThread::run() +{ + sleep(3); + QDBusInterface interface( "org.freedesktop.NetworkManager", + "/org/freedesktop/NetworkManager", + "org.freedesktop.NetworkManager", + QDBusConnection::systemBus() ); + QDBusReply reply= interface.call("CheckConnectivity"); + if (reply.isValid()) { + //qDebug()<<"---------------------wifi type:----------------------"< +#include +#include +#include +#include +#include +#include + +class WifiAuthThread:public QThread +{ +protected: + virtual void run(); + QNetworkRequest request; + QNetworkAccessManager* naManager=nullptr; + bool _isConnect=true;//是否已联网 + bool _isReply=false;//联网状态检查是否收到回复 + +public: + WifiAuthThread(); + ~WifiAuthThread(); +}; + +#endif //WIFI_AUTH_THREAD_H diff --git a/src/frontend/customstyle.cpp b/src/frontend/customstyle.cpp new file mode 100644 index 00000000..7c5c3397 --- /dev/null +++ b/src/frontend/customstyle.cpp @@ -0,0 +1,152 @@ +#include "customstyle.h" + +CustomStyle::CustomStyle(const QString &proxyStyleName) : QProxyStyle (proxyStyleName) +{ + +} + +QSize CustomStyle::sizeFromContents(QStyle::ContentsType type, const QStyleOption *option, const QSize &contentsSize, const QWidget *widget) const +{ + switch (type) { + case CT_TabBarTab: { + QSize size(0,40); + if (const QStyleOptionTab *tab= qstyleoption_cast(option)) { + switch (tab->shape) { + case QTabBar::RoundedNorth: + case QTabBar::RoundedSouth: { + return size + QSize(50,0); + break; + } + case QTabBar::RoundedWest: + case QTabBar::RoundedEast: { + return size + QSize(0,50); + break; + } + default: { + break; + } + } + } + return size; + break; + } + default: { + break; + } + } + return QProxyStyle::sizeFromContents(type, option, contentsSize, widget); +} +void CustomStyle::drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const +{ +// switch (element) { +// case CE_TabBarTab: { +// if (QStyle::State_Selected != option->state) { +// painter->save(); +// painter->setBrush(QColor(0,0,0,0)); +// painter->drawRect(widget->rect()); +//// painter->setOpacity(0.1); +// painter->restore(); +// } +// break; +// } +// default: { +// break; +// } +// } + return QProxyStyle::drawControl(element, option, painter, widget); +} + +//void CustomStyle::drawComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const +//{ +// return QProxyStyle::drawComplexControl(control, option, painter, widget); +//} + +//void CustomStyle::drawItemPixmap(QPainter *painter, const QRect &rectangle, int alignment, const QPixmap &pixmap) const +//{ +// return QProxyStyle::drawItemPixmap(painter, rectangle, alignment, pixmap); +//} + +//void CustomStyle::drawItemText(QPainter *painter, const QRect &rectangle, int alignment, const QPalette &palette, bool enabled, const QString &text, QPalette::ColorRole textRole) const +//{ +// return QProxyStyle::drawItemText(painter, rectangle, alignment, palette, enabled, text, textRole); +//} + +//void CustomStyle::drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const +//{ +// return QProxyStyle::drawPrimitive(element, option, painter, widget); +//} + +//QPixmap CustomStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *option) const +//{ +// return QProxyStyle::generatedIconPixmap(iconMode, pixmap, option); +//} + +//QStyle::SubControl CustomStyle::hitTestComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, const QPoint &position, const QWidget *widget) const +//{ +// return QProxyStyle::hitTestComplexControl(control, option, position, widget); +//} + +//QRect CustomStyle::itemPixmapRect(const QRect &rectangle, int alignment, const QPixmap &pixmap) const +//{ +// return QProxyStyle::itemPixmapRect(rectangle, alignment, pixmap); +//} + +//QRect CustomStyle::itemTextRect(const QFontMetrics &metrics, const QRect &rectangle, int alignment, bool enabled, const QString &text) const +//{ +// return QProxyStyle::itemTextRect(metrics, rectangle, alignment, enabled, text); +//} + +//int CustomStyle::pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option, const QWidget *widget) const +//{ +// return QProxyStyle::pixelMetric(metric, option, widget); +//} + +//void CustomStyle::polish(QWidget *widget) +//{ +// return QProxyStyle::polish(widget); +//} + +//void CustomStyle::polish(QApplication *application) +//{ +// return QProxyStyle::polish(application); +//} + +//void CustomStyle::polish(QPalette &palette) +//{ +// return QProxyStyle::polish(palette); +//} + +//void CustomStyle::unpolish(QWidget *widget) +//{ +// return QProxyStyle::unpolish(widget); +//} + +//void CustomStyle::unpolish(QApplication *application) +//{ +// return QProxyStyle::unpolish(application); +//} + +//QIcon CustomStyle::standardIcon(QStyle::StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const +//{ +// return QProxyStyle::standardIcon(standardIcon, option, widget); +//} + +//QPalette CustomStyle::standardPalette() const +//{ +// return QProxyStyle::standardPalette(); +//} + +//int CustomStyle::styleHint(QStyle::StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const +//{ +// return QProxyStyle::styleHint(hint, option, widget, returnData); +//} + +//QRect CustomStyle::subControlRect(QStyle::ComplexControl control, const QStyleOptionComplex *option, QStyle::SubControl subControl, const QWidget *widget) const +//{ +// return QProxyStyle::subControlRect(control, option, subControl, widget); +//} + +//QRect CustomStyle::subElementRect(QStyle::SubElement element, const QStyleOption *option, const QWidget *widget) const +//{ +// return QProxyStyle::subElementRect(element, option, widget); +//} diff --git a/src/frontend/customstyle.h b/src/frontend/customstyle.h new file mode 100644 index 00000000..85245ccb --- /dev/null +++ b/src/frontend/customstyle.h @@ -0,0 +1,47 @@ +#ifndef CUSTOMSTYLE_H +#define CUSTOMSTYLE_H + +#include +#include +#include +#include +#include +#include +#include + +class CustomStyle : public QProxyStyle +{ + Q_OBJECT +public: + explicit CustomStyle(const QString &proxyStyleName = "windows"); + ~CustomStyle() = default; + virtual QSize sizeFromContents(QStyle::ContentsType type, const QStyleOption *option, const QSize &contentsSize, const QWidget *widget = nullptr) const; + virtual void drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const; +// virtual void drawComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = nullptr) const; + +// virtual void drawItemPixmap(QPainter *painter, const QRect &rectangle, int alignment, const QPixmap &pixmap) const; +// virtual void drawItemText(QPainter *painter, const QRect &rectangle, int alignment, const QPalette &palette, bool enabled, const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const; + +// virtual void drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const; +// virtual QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *option) const; +// virtual QStyle::SubControl hitTestComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, const QPoint &position, const QWidget *widget = nullptr) const; +// virtual QRect itemPixmapRect(const QRect &rectangle, int alignment, const QPixmap &pixmap) const; +// virtual QRect itemTextRect(const QFontMetrics &metrics, const QRect &rectangle, int alignment, bool enabled, const QString &text) const; +// //virtual int layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, Qt::Orientation orientation, const QStyleOption *option, const QWidget *widget); +// virtual int pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option = nullptr, const QWidget *widget = nullptr) const; + +// virtual void polish(QWidget *widget); +// virtual void polish(QApplication *application); +// virtual void polish(QPalette &palette); +// virtual void unpolish(QWidget *widget); +// virtual void unpolish(QApplication *application); + +// virtual QIcon standardIcon(QStyle::StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const; +// virtual QPalette standardPalette() const; + +// virtual int styleHint(QStyle::StyleHint hint, const QStyleOption *option = nullptr, const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const; +// virtual QRect subControlRect(QStyle::ComplexControl control, const QStyleOptionComplex *option, QStyle::SubControl subControl, const QWidget *widget = nullptr) const; +// virtual QRect subElementRect(QStyle::SubElement element, const QStyleOption *option, const QWidget *widget = nullptr) const; +}; + +#endif // CUSTOMSTYLE_H diff --git a/src/frontend/enterprise-wlan/enterprise-wlan.pri b/src/frontend/enterprise-wlan/enterprise-wlan.pri new file mode 100644 index 00000000..c4571359 --- /dev/null +++ b/src/frontend/enterprise-wlan/enterprise-wlan.pri @@ -0,0 +1,9 @@ +INCLUDEPATH += $$PWD + +FORMS += \ + +HEADERS += \ + $$PWD/enterprisewlandialog.h \ + +SOURCES += \ + $$PWD/enterprisewlandialog.cpp \ diff --git a/src/frontend/enterprise-wlan/enterprisewlandialog.cpp b/src/frontend/enterprise-wlan/enterprisewlandialog.cpp new file mode 100644 index 00000000..30dd8941 --- /dev/null +++ b/src/frontend/enterprise-wlan/enterprisewlandialog.cpp @@ -0,0 +1,214 @@ +#include "enterprisewlandialog.h" +#include +#include +#include "xatom-helper.h" +#define MAIN_SIZE_EXPAND 400,500 +#define MAIN_SIZE_NARROW 400,400 + +#define THEME_SCHAME "org.ukui.style" +#define COLOR_THEME "styleName" + +EnterpriseWlanDialog::EnterpriseWlanDialog(KyWirelessNetItem &wirelessNetItem, QString device, QWidget *parent) : QWidget(parent) +{ + //设置窗口无边框,阴影 +#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) + MotifWmHints window_hints; + window_hints.flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS; + window_hints.functions = MWM_FUNC_ALL; + window_hints.decorations = MWM_DECOR_BORDER; + XAtomHelper::getInstance()->setWindowMotifHint(this->winId(), window_hints); +#else + this->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint); +#endif + this->setAttribute(Qt::WA_DeleteOnClose); + this->setWindowFlag(Qt::Window); + this->setWindowTitle(tr("Connect Enterprise WLAN")); + + m_wirelessNetItem = wirelessNetItem; + m_deviceName = device; + m_connectOperation = new KyWirelessConnectOperation(); + m_resource = new KyWirelessNetResource(); + + initUI(); + initData(); + centerToScreen(); +} + +EnterpriseWlanDialog::~EnterpriseWlanDialog() { + if (m_securityPage) { + delete m_securityPage; + m_securityPage = nullptr; + } + if (m_connectOperation) { + delete m_connectOperation; + m_connectOperation = nullptr; + } +} + +void EnterpriseWlanDialog::closeEvent(QCloseEvent *event) +{ + emit this->enterpriseWlanDialogClose(false); + return QWidget::closeEvent(event); +} + +void EnterpriseWlanDialog::initUI() +{ +#define MAIN_LAYOUT_MARGINS 8,8,8,8 +#define SSID_LAYOUT_MARGINS 8,8,8,0 +#define MAIN_LAYOUT_SPACING 0 +#define BUTTON_SPACING 8 + + m_mainLayout = new QVBoxLayout(this); + this->setLayout(m_mainLayout); + m_mainLayout->setContentsMargins(MAIN_LAYOUT_MARGINS); + m_mainLayout->setSpacing(MAIN_LAYOUT_SPACING); + + m_ssidLayout = new QHBoxLayout(); + m_ssidLayout->setContentsMargins(SSID_LAYOUT_MARGINS); + m_ssidTitleLabel = new QLabel(this); + m_ssidTitleLabel->setText("SSID"); + m_ssidLabel = new QLabel(this); + m_ssidLabel->setText(m_wirelessNetItem.m_NetSsid); + + m_ssidLayout->addWidget(m_ssidTitleLabel); + m_ssidLayout->addStretch(); + m_ssidLayout->addWidget(m_ssidLabel); + + m_securityPage = new SecurityPage(this); + m_securityPage->setSecurity(KySecuType::WPA_AND_WPA2_ENTERPRISE); + m_securityPage->setSecurityVisible(false); + + m_btnLayout = new QHBoxLayout(); + m_btnLayout->setSpacing(BUTTON_SPACING); + m_cancelBtn = new QPushButton(this); + m_connectBtn = new QPushButton(this); + m_cancelBtn->setText(tr("Cancel")); + m_connectBtn->setText(tr("Connect")); + m_connectBtn->setEnabled(false); + m_btnLayout->addStretch(); + m_btnLayout->addWidget(m_cancelBtn); + m_btnLayout->addWidget(m_connectBtn); + m_mainLayout->addLayout(m_ssidLayout); + m_mainLayout->addWidget(m_securityPage); + m_mainLayout->addLayout(m_btnLayout); + m_mainLayout->addStretch(); + + this->setFixedSize(MAIN_SIZE_EXPAND); + initConnections(); + onPaletteChanged(); +} + +void EnterpriseWlanDialog::centerToScreen() +{ + QDesktopWidget* m = QApplication::desktop(); + QRect desk_rect = m->screenGeometry(m->screenNumber(QCursor::pos())); + int desk_x = desk_rect.width(); + int desk_y = desk_rect.height(); + int x = this->width(); + int y = this->height(); + this->move(desk_x / 2 - x / 2 + desk_rect.left(), desk_y / 2 - y / 2 + desk_rect.top()); +} + +void EnterpriseWlanDialog::initConnections() +{ + connect(m_closeBtn, &QPushButton::clicked, this, &EnterpriseWlanDialog::close); + connect(m_cancelBtn, &QPushButton::clicked, this, &EnterpriseWlanDialog::close); + connect(m_connectBtn, &QPushButton::clicked, this, &EnterpriseWlanDialog::onBtnConnectClicked); + connect(m_securityPage, &SecurityPage::eapTypeChanged, this, &EnterpriseWlanDialog::onEapTypeChanged); + connect(m_securityPage, &SecurityPage::setSecuPageState, this, [ = ](bool status) { + m_connectBtn->setEnabled(status); + }); + + connect(qApp, &QApplication::paletteChanged, this, &EnterpriseWlanDialog::onPaletteChanged); +} + +void EnterpriseWlanDialog::onPaletteChanged() +{ + QPalette pal = qApp->palette(); + + QGSettings * styleGsettings = nullptr; + const QByteArray style_id(THEME_SCHAME); + if (QGSettings::isSchemaInstalled(style_id)) { + styleGsettings = new QGSettings(style_id); + QString currentTheme = styleGsettings->get(COLOR_THEME).toString(); + if(currentTheme == "ukui-default"){ + pal = lightPalette(this); + } + } + + this->setPalette(pal); + + setFramePalette(m_securityPage, pal); +} + +void EnterpriseWlanDialog::initData() +{ + if (m_wirelessNetItem.m_isConfigured) { + KyEapMethodType type; + m_connectOperation->getEnterpiseEapMethod(m_wirelessNetItem.m_connectUuid, type); + if (type) { + onEapTypeChanged(type); + } else { + qWarning() << "Get eap type failed!" << Q_FUNC_INFO << __LINE__; + } + } +} + +void EnterpriseWlanDialog::onBtnConnectClicked() +{ + qDebug() << "Clicked connectBtn, will connect enterprise WLAN, ssid = " + << m_wirelessNetItem.m_NetSsid << "." << Q_FUNC_INFO << __LINE__; + KySecuType secuType; + KyEapMethodType eapType; + m_securityPage->getSecuType(secuType, eapType); + + KyWirelessConnectSetting connetSetting; + connetSetting.setConnectName(m_wirelessNetItem.m_NetSsid); + connetSetting.setIfaceName(m_deviceName); + connetSetting.isAutoConnect = true; //ZJP_TODO 自动连接选项 + connetSetting.m_type = KyKeyMgmt::WpaEap; + connetSetting.m_ssid = m_wirelessNetItem.m_NetSsid; + connetSetting.m_secretFlag = 0; + connetSetting.dumpInfo(); + + if (eapType == KyEapMethodType::TLS) { + m_info.tlsInfo.devIfaceName = m_deviceName; + m_securityPage->updateTlsChange(m_info.tlsInfo); + m_connectOperation->addAndActiveWirelessEnterPriseTlsConnect(m_info.tlsInfo, connetSetting, m_deviceName, false); + } else if (eapType == KyEapMethodType::PEAP) { + m_securityPage->updatePeapChange(m_info.peapInfo); + m_connectOperation->addAndActiveWirelessEnterPrisePeapConnect(m_info.peapInfo, connetSetting, m_deviceName, false); + } else if (eapType == KyEapMethodType::TTLS) { + m_securityPage->updateTtlsChange(m_info.ttlsInfo); + m_connectOperation->addAndActiveWirelessEnterPriseTtlsConnect(m_info.ttlsInfo, connetSetting, m_deviceName, false); + } else { + qWarning() << "Connect enterprise wlan failed!(Unknown eap type)" << Q_FUNC_INFO << __LINE__; + } + close(); +} + +void EnterpriseWlanDialog::onEapTypeChanged(const KyEapMethodType &type) +{ + switch (type) { + case KyEapMethodType::TLS: + if (!m_wirelessNetItem.m_connectUuid.isEmpty()) { + m_resource->getEnterPriseInfoTls(m_wirelessNetItem.m_connectUuid, m_info.tlsInfo); + } + this->setFixedSize(MAIN_SIZE_EXPAND); + break; + case KyEapMethodType::PEAP: + if (m_wirelessNetItem.m_connectUuid.isEmpty()) { + m_resource->getEnterPriseInfoPeap(m_wirelessNetItem.m_connectUuid, m_info.peapInfo); + } + this->setFixedSize(MAIN_SIZE_NARROW); + break; + case KyEapMethodType::TTLS: + if (!m_wirelessNetItem.m_connectUuid.isEmpty()) { + m_resource->getEnterPriseInfoTtls(m_wirelessNetItem.m_connectUuid, m_info.ttlsInfo); + } + this->setFixedSize(MAIN_SIZE_NARROW); + break; + default: + break; + } +} diff --git a/src/frontend/enterprise-wlan/enterprisewlandialog.h b/src/frontend/enterprise-wlan/enterprisewlandialog.h new file mode 100644 index 00000000..3b094592 --- /dev/null +++ b/src/frontend/enterprise-wlan/enterprisewlandialog.h @@ -0,0 +1,65 @@ +#ifndef ENTERPRISEWLANDIALOG_H +#define ENTERPRISEWLANDIALOG_H +#include +#include +#include "securitypage.h" +#include "kywirelessnetitem.h" +#include "coninfo.h" + +class EnterpriseWlanDialog : public QWidget +{ + Q_OBJECT +public: + EnterpriseWlanDialog(KyWirelessNetItem &wirelessNetItem, QString device, QWidget *parent = nullptr); + ~EnterpriseWlanDialog(); + +protected: + void closeEvent(QCloseEvent *event); + +private: + void initUI(); //初始化UI界面 + void centerToScreen(); + void initConnections(); + void initData(); + +private: + KyWirelessNetItem m_wirelessNetItem; + ConInfo m_info; + QString m_deviceName; + KyWirelessConnectOperation *m_connectOperation = nullptr; + KyWirelessNetResource *m_resource = nullptr; + + /* 弹窗布局 + * Connect Enterprise WLAN············X + * SSID··························[SSID] + * -----------SecurityPage------------- + * | | + * ------------------------------------ + * ····················CANCEL···CONNECT + */ + QVBoxLayout *m_mainLayout = nullptr; + + QHBoxLayout *m_titleLayout = nullptr; + QLabel *m_titleLabel = nullptr; + QPushButton *m_closeBtn = nullptr; + + QHBoxLayout *m_ssidLayout = nullptr; + QLabel *m_ssidTitleLabel = nullptr; + QLabel *m_ssidLabel = nullptr; + + SecurityPage *m_securityPage = nullptr; + + QHBoxLayout *m_btnLayout = nullptr; + QPushButton *m_cancelBtn = nullptr; + QPushButton *m_connectBtn = nullptr; + +private slots: + void onBtnConnectClicked(); + void onEapTypeChanged(const KyEapMethodType &type); + void onPaletteChanged(); + +signals: + void enterpriseWlanDialogClose(bool); +}; + +#endif // ENTERPRISEWLANDIALOG_H diff --git a/src/frontend/frontend.pri b/src/frontend/frontend.pri new file mode 100644 index 00000000..ec60ca6c --- /dev/null +++ b/src/frontend/frontend.pri @@ -0,0 +1,20 @@ +INCLUDEPATH += $$PWD +include(tools/tools.pri) +include(xatom/xatom.pri) +include(tab-pages/tab-pages.pri) +include(list-items/list-items.pri) +include(netdetails/netdetails.pri) +include(enterprise-wlan/enterprise-wlan.pri) + +FORMS += \ + $$PWD/wificonfigdialog.ui + +HEADERS += \ + $$PWD/customstyle.h \ + $$PWD/mainwindow.h \ + $$PWD/wificonfigdialog.h + +SOURCES += \ + $$PWD/customstyle.cpp \ + $$PWD/mainwindow.cpp \ + $$PWD/wificonfigdialog.cpp diff --git a/src/frontend/list-items/lanlistitem.cpp b/src/frontend/list-items/lanlistitem.cpp new file mode 100644 index 00000000..18e8e4e1 --- /dev/null +++ b/src/frontend/list-items/lanlistitem.cpp @@ -0,0 +1,222 @@ +#include "lanlistitem.h" +#include "backend/dbus-interface/kylinconnectitem.h" + +#include + +#define LOG_FLAG "[LanListItem]" + +LanListItem::LanListItem(const KyConnectItem *lanConnectItem, + const QString &deviceName, QWidget *parent):ListItem(parent) +{ + m_connectOperation = new KyWiredConnectOperation(this); + m_deviceResource = new KyNetworkDeviceResourse(this); + + connectItemCopy(lanConnectItem); + m_deviceName = deviceName; + + m_nameLabel->setText(m_lanConnectItem.m_connectName); + m_netButton->setButtonIcon(QIcon::fromTheme("network-wired-connected-symbolic")); + + qDebug() << "LanListItem init:" << m_lanConnectItem.m_connectName << m_lanConnectItem.m_connectState << m_lanConnectItem.m_ifaceName; + + if (Deactivated == m_lanConnectItem.m_connectState || Activated == m_lanConnectItem.m_connectState) { + m_netButton->stopLoading(); + if (m_lanConnectItem.m_connectState == Activated) { + setIcon(true); + } else { + setIcon(false); + } + } else { + m_netButton->startLoading(); + } + + m_itemFrame->installEventFilter(this); + connect(this->m_infoButton, &InfoButton::clicked, this, &LanListItem::onInfoButtonClicked); + connect(m_menu, &QMenu::triggered, this, &LanListItem::onMenuTriggered); +} + + +LanListItem::LanListItem(QWidget *parent) : ListItem(parent) +{ + m_isActive = false; + m_netButton->setButtonIcon(QIcon::fromTheme("network-wired-disconnected-symbolic")); + setIcon(false); + const QString str=tr("Not connected"); + m_nameLabel->setText(str); + this->m_infoButton->hide(); +} + +LanListItem::~LanListItem() +{ + qDebug()<<"[LanPage] lan list item is deleted." << m_lanConnectItem.m_connectName; +} + +void LanListItem::setIcon(bool isOn) +{ + if (isOn) { + m_netButton->setActive(true); //设置图标显示不同颜色 + } else { + m_netButton->setActive(false); + } +} + +void LanListItem::connectItemCopy(const KyConnectItem *lanConnectItem) +{ + if (lanConnectItem) { + m_lanConnectItem.m_connectName = lanConnectItem->m_connectName; + m_lanConnectItem.m_connectPath = lanConnectItem->m_connectPath; + m_lanConnectItem.m_connectState = lanConnectItem->m_connectState; + m_lanConnectItem.m_connectUuid = lanConnectItem->m_connectUuid; + m_lanConnectItem.m_ifaceName = lanConnectItem->m_ifaceName; + m_lanConnectItem.m_itemType = lanConnectItem->m_itemType; + } else { + qDebug() << LOG_FLAG <<"the connect item is nullptr"; + m_lanConnectItem.m_connectName = ""; + m_lanConnectItem.m_connectPath = ""; + m_lanConnectItem.m_connectState = NetworkManager::ActiveConnection::State::Unknown; + m_lanConnectItem.m_connectUuid = ""; + m_lanConnectItem.m_ifaceName = ""; + m_lanConnectItem.m_itemType = NetworkManager::ConnectionSettings::ConnectionType::Unknown; + } + + return; +} + +void LanListItem::onNetButtonClicked() +{ + if (m_lanConnectItem.m_connectUuid.isEmpty()) { + qDebug() << LOG_FLAG << "connect is empty, so can not connect or disconnect."; + return; + } + + if (Deactivated == m_lanConnectItem.m_connectState) { + //断开的连接,点击激活连接 + if (m_deviceResource->wiredDeviceIsCarriered(m_deviceName)) { + m_connectOperation->activateWiredConnection(m_lanConnectItem.m_connectUuid, m_deviceName); + qDebug() << LOG_FLAG << "it will activate connection" << m_lanConnectItem.m_connectName + << ". it's device is" << m_deviceName; + m_netButton->startLoading(); + } else { + qDebug() << LOG_FLAG << m_deviceName << "is not carried, so can not activate connection"; + this->showDesktopNotify(tr("Wired Device not carried")); + } + } else { + qDebug() << LOG_FLAG <<"the connection" << m_lanConnectItem.m_connectName + << "is not deactived, so it can not be operation."; + } + + return; + +} + +void LanListItem::onRightButtonClicked() +{ + //右键点击事件 + qDebug()<< LOG_FLAG <<"onRightButtonClicked"; + if (!m_menu) { + return; + } + + m_menu->clear(); + if (Activated == m_lanConnectItem.m_connectState || Activating == m_lanConnectItem.m_connectState) { + m_menu->addAction(new QAction(tr("Disconnect"), this)); + } else if (Deactivated == m_lanConnectItem.m_connectState) { + m_menu->addAction(new QAction(tr("Connect"), this)); + } else { + return; + } + + m_menu->move(cursor().pos()); + m_menu->show(); + return; +} + +void LanListItem::onMenuTriggered(QAction *action) +{ + if (action->text() == tr("Connect")) { + this->onNetButtonClicked(); + } else if (action->text() == tr("Disconnect")) { + m_connectOperation->deactivateWiredConnection(m_lanConnectItem.m_connectName, m_lanConnectItem.m_connectUuid); + qDebug() << LOG_FLAG << "it will disconnect connection" << m_lanConnectItem.m_connectName + << ". it's device is" << m_deviceName; + m_netButton->startLoading(); + } + return; +} + + +void LanListItem::onInfoButtonClicked() +{ + if (m_lanConnectItem.m_connectUuid.isEmpty()) { + qDebug() << LOG_FLAG << "connect is empty, so can not show detail info."; + return; + } + + if(netDetail != nullptr){ + netDetail->activateWindow(); + return; + } + + qDebug()<< LOG_FLAG << "the info button of lan is clicked! uuid = " + << m_lanConnectItem.m_connectUuid << "; name = " << m_lanConnectItem.m_connectName + << "." <show(); + emit this->detailShow(true); + + return; +} + +void LanListItem::updateConnectionState(ConnectState state) +{ + m_lanConnectItem.m_connectState = (NetworkManager::ActiveConnection::State)state; + + if (Deactivated == state || Activated == state) { + m_netButton->stopLoading(); + if (state == Activated) { + setIcon(true); + } else { + setIcon(false); + } + } else { + m_netButton->startLoading(); + } + + return; +} + +QString LanListItem::getConnectionName() +{ + return m_lanConnectItem.m_connectName; +} + +void LanListItem::updateConnectionName(QString connectionName) +{ + m_lanConnectItem.m_connectName = connectionName; + m_nameLabel->setText(m_lanConnectItem.m_connectName); + return; +} + +QString LanListItem::getConnectionPath() +{ + return m_lanConnectItem.m_connectPath; +} + +void LanListItem::updateConnectionPath(QString connectionPath) +{ + m_lanConnectItem.m_connectPath = connectionPath; +} diff --git a/src/frontend/list-items/lanlistitem.h b/src/frontend/list-items/lanlistitem.h new file mode 100644 index 00000000..c778e7eb --- /dev/null +++ b/src/frontend/list-items/lanlistitem.h @@ -0,0 +1,50 @@ +#ifndef LANLISTITEM_H +#define LANLISTITEM_H +#include "listitem.h" +#include "kylinactiveconnectresource.h" + +#include +#include +#include + +class LanListItem : public ListItem +{ + Q_OBJECT + +public: + LanListItem(const KyConnectItem *lanConnectItem, const QString &deviceName, QWidget *parent = nullptr); + LanListItem(QWidget *parent = nullptr); + + ~LanListItem(); + +public: + void updateConnectionState(ConnectState state); + + QString getConnectionName(); + void updateConnectionName(QString connectionName); + + QString getConnectionPath(); + void updateConnectionPath(QString connectionPath); + +protected: + void setIcon(bool isOn); + void onRightButtonClicked(); + +private: + void connectItemCopy(const KyConnectItem *lanConnectItem); + +private slots: + void onInfoButtonClicked(); + void onNetButtonClicked(); + void onMenuTriggered(QAction *action); + +private: + KyConnectItem m_lanConnectItem; + + KyWiredConnectOperation *m_connectOperation = nullptr; + KyNetworkDeviceResourse *m_deviceResource = nullptr; + + QString m_deviceName = ""; +}; + +#endif // LANLISTITEM_H diff --git a/src/frontend/list-items/list-items.pri b/src/frontend/list-items/list-items.pri new file mode 100644 index 00000000..8fdc468e --- /dev/null +++ b/src/frontend/list-items/list-items.pri @@ -0,0 +1,18 @@ +INCLUDEPATH += $$PWD + +FORMS += \ + $$PWD/oneconnform.ui \ + $$PWD/onelancform.ui + +HEADERS += \ + $$PWD/lanlistitem.h \ + $$PWD/listitem.h \ + $$PWD/wlanlistitem.h \ + $$PWD/wlanmoreitem.h + +SOURCES += \ + $$PWD/lanlistitem.cpp \ + $$PWD/listitem.cpp \ + $$PWD/wlanlistitem.cpp \ + $$PWD/wlanmoreitem.cpp + diff --git a/src/frontend/list-items/listitem.cpp b/src/frontend/list-items/listitem.cpp new file mode 100644 index 00000000..1c459ce7 --- /dev/null +++ b/src/frontend/list-items/listitem.cpp @@ -0,0 +1,166 @@ +#include "listitem.h" +#include + +#define MAIN_LAYOUT_MARGINS 0,0,0,0 +#define MAIN_LAYOUT_SPACING 0 +#define ITEM_FRAME_MARGINS 16,6,16,6 +#define ITEM_FRAME_SPACING 10 +#define FRAME_WIDTH 395 +#define INFO_ICON_WIDTH 16 +#define INFO_ICON_HEIGHT 16 +#define LIGHT_HOVER_COLOR QColor(240,240,240,255) +#define DARK_HOVER_COLOR QColor(15,15,15,255) + +ListItem::ListItem(QWidget *parent) : QFrame(parent) +{ + m_connectState = UnknownState; + + initUI(); + initConnection(); + connect(qApp, &QApplication::paletteChanged, this, &ListItem::onPaletteChanged); +// m_itemFrame->installEventFilter(this); +} + +ListItem::~ListItem() +{ + if (nullptr != m_netButton) { + delete m_netButton; + m_netButton = nullptr; + } + + if (nullptr != m_infoButton) { + delete m_infoButton; + m_infoButton = nullptr; + } + +} + +void ListItem::setName(const QString &name) +{ + m_nameLabel->setText(name); +} + +//仅无线调用,有线自己获取 +void ListItem::setActive(const bool &isActive) +{ + m_netButton->setActive(isActive); + m_isActive = isActive; +} + +void ListItem::setConnectState(ConnectState state) +{ + m_connectState = state; +} + +void ListItem::showDesktopNotify(const QString &message) +{ + QDBusInterface iface("org.freedesktop.Notifications", + "/org/freedesktop/Notifications", + "org.freedesktop.Notifications", + QDBusConnection::sessionBus()); + QList args; + args<<(tr("Kylin NM")) + <<((unsigned int) 0) + <button() == Qt::LeftButton) { + onNetButtonClicked(); + } else if (event->button() == Qt::RightButton) { + onRightButtonClicked(); + } + return QFrame::mousePressEvent(event); +} + +void ListItem::enterEvent(QEvent *event) +{ +// QPalette pal = qApp->palette(); +// QColor baseColor = qApp->palette().base().color(); +// if (baseColor.red() > MIDDLE_COLOR) { +// pal.setColor(QPalette::Window, LIGHT_HOVER_COLOR); +// } else { +// pal.setColor(QPalette::Window, DARK_HOVER_COLOR); +// } +// this->setPalette(pal); +// return QFrame::enterEvent(event); +} + +void ListItem::leaveEvent(QEvent *event) +{ +// QPalette pal = qApp->palette(); +// pal.setColor(QPalette::Window, qApp->palette().base().color()); +// this->setPalette(pal); +// return QFrame::leaveEvent(event); +} + +void ListItem::paintEvent(QPaintEvent *event) +{ +// QPainter painter(this); +// painter.setRenderHint(QPainter::Antialiasing); //反锯齿 +// painter.setBrush(this->palette().brush(QPalette::Window)); +// painter.setPen(Qt::transparent); +// painter.drawRoundedRect(this->rect(), 6, 6); +// return QFrame::paintEvent(event); +} + +void ListItem::initUI() +{ + m_menu = new QMenu(this);//右键菜单 +// m_menu->setStyleSheet("QMenu::item{border:3px; border-radius:3px}"); +// m_menu->setStyleSheet("QMenu{border-radius:6px; margin:6px 6px 6px 6px}"); + connect(m_menu, &QMenu::triggered, this, &ListItem::onMenuTriggered); + + m_mainLayout = new QVBoxLayout(this); + m_mainLayout->setContentsMargins(MAIN_LAYOUT_MARGINS); + m_mainLayout->setSpacing(MAIN_LAYOUT_SPACING); + this->setLayout(m_mainLayout); + + m_itemFrame = new QFrame(this); + m_itemFrame->setFixedWidth(FRAME_WIDTH); + + m_hItemLayout = new QHBoxLayout(m_itemFrame); + m_hItemLayout->setContentsMargins(ITEM_FRAME_MARGINS); +// m_hItemLayout->setSpacing(ITEM_FRAME_SPACING); + + m_netButton = new RadioItemButton(m_itemFrame); + m_nameLabel = new FixLabel(m_itemFrame); + m_infoButton = new InfoButton(m_itemFrame); + m_infoButton->setIconSize(QSize(INFO_ICON_WIDTH,INFO_ICON_HEIGHT)); + + m_hItemLayout->addWidget(m_netButton); + m_hItemLayout->addWidget(m_nameLabel); + m_hItemLayout->addStretch(); + m_hItemLayout->addWidget(m_infoButton); + + m_mainLayout->addWidget(m_itemFrame); + +// this->setAutoFillBackground(true); +// this->setBackgroundRole(QPalette::Base); +// QPalette pal = qApp->palette(); +// pal.setColor(QPalette::Window, qApp->palette().base().color()); +// this->setPalette(pal); +} + + +void ListItem::initConnection() +{ + connect(this->m_netButton, &RadioItemButton::clicked, this, &ListItem::onNetButtonClicked); + // connect(this->m_infoButton, &InfoButton::clicked, this, &ListItem::onInfoButtonClicked); +} + +void ListItem::onPaletteChanged() +{ +// QPalette pal = qApp->palette(); +// pal.setColor(QPalette::Window, qApp->palette().base().color()); +// this->setPalette(pal); +} + diff --git a/src/frontend/list-items/listitem.h b/src/frontend/list-items/listitem.h new file mode 100644 index 00000000..c78c2799 --- /dev/null +++ b/src/frontend/list-items/listitem.h @@ -0,0 +1,68 @@ +#ifndef LISTITEM_H +#define LISTITEM_H +#include +#include +#include +#include +#include +#include +#include "radioitembutton.h" +#include "infobutton.h" +#include "netdetails/netdetail.h" + +typedef enum{ + UnknownState = 0, /**< The active connection is in an unknown state */ + Activating, /**< The connection is activating */ + Activated, /**< The connection is activated */ + Deactivating, /**< The connection is being torn down and cleaned up */ + Deactivated /**< The connection is no longer active */ +}ConnectState; + +class ListItem : public QFrame +{ + Q_OBJECT +public: + ListItem(QWidget *parent = nullptr); + ~ListItem(); + void setName(const QString &name); + void setActive(const bool &isActive); + void setConnectState(ConnectState state); + static void showDesktopNotify(const QString &message); + +protected: + void mousePressEvent(QMouseEvent *event); + void enterEvent(QEvent *event); + void leaveEvent(QEvent *event); + void paintEvent(QPaintEvent *event); + virtual void onRightButtonClicked() = 0; + +protected: + QFrame * m_itemFrame = nullptr; + + FixLabel * m_nameLabel = nullptr; + RadioItemButton * m_netButton = nullptr; + InfoButton * m_infoButton = nullptr; + + bool m_isActive = false; + ConnectState m_connectState; + + QMenu *m_menu = nullptr; +public: + QVBoxLayout * m_mainLayout = nullptr; + QHBoxLayout * m_hItemLayout = nullptr; + + NetDetail *netDetail = nullptr; +private: + void initUI(); + void initConnection(); + +public slots: + virtual void onNetButtonClicked() = 0; + void onPaletteChanged(); + virtual void onMenuTriggered(QAction *action)=0; + +signals: + void detailShow(bool isShow); +}; + +#endif // LISTITEM_H diff --git a/src/frontend/list-items/oneconnform.ui b/src/frontend/list-items/oneconnform.ui new file mode 100644 index 00000000..9e47beaa --- /dev/null +++ b/src/frontend/list-items/oneconnform.ui @@ -0,0 +1,302 @@ + + + OneConnForm + + + + 0 + 0 + 424 + 142 + + + + Form + + + + + 63 + 8 + 241 + 20 + + + + + + + + + + 316 + 14 + 100 + 34 + + + + + + + + + + 316 + 14 + 100 + 34 + + + + + + + + + + 14 + 14 + 32 + 32 + + + + + + + + + + 63 + 31 + 140 + 20 + + + + + + + + + + 0 + 0 + 424 + 106 + + + + + + 64 + 64 + 352 + 30 + + + + + + + 390 + 75 + 18 + 9 + + + + + + + + + + + 316 + 14 + 100 + 34 + + + + + + + + + + 316 + 14 + 100 + 34 + + + + + + + + + + 316 + 14 + 100 + 34 + + + + + + + + + + 0 + 0 + 424 + 138 + + + + + + 63 + 64 + 230 + 61 + + + + + + + + + + 63 + 62 + 230 + 20 + + + + + + + + + + 63 + 86 + 230 + 20 + + + + + + + + + + 63 + 110 + 230 + 20 + + + + + + + leInfo_1 + leInfo_2 + leInfo_3 + btnInfo + + + + + 2 + 59 + 421 + 2 + + + + background-color: rgba(156, 156, 156,0.1); + + + Qt::Horizontal + + + + + + 0 + 0 + 424 + 60 + + + + + + + 316 + 14 + 100 + 34 + + + + + + + + + + 380 + 20 + 20 + 20 + + + + + + + + + + 316 + 14 + 70 + 34 + + + + + + + wbg_3 + wbg_2 + lbName + lbSignal + lbConned + line + wbg + btnConnSub + btnConn + btnConnPWD + btnDisConn + btnHideConn + lbWaiting + lbWaitingIcon + btnCancel + + + + diff --git a/src/frontend/list-items/onelancform.ui b/src/frontend/list-items/onelancform.ui new file mode 100644 index 00000000..ee3f4a06 --- /dev/null +++ b/src/frontend/list-items/onelancform.ui @@ -0,0 +1,254 @@ + + + OneLancForm + + + + 0 + 0 + 424 + 167 + + + + Form + + + + + 63 + 8 + 190 + 20 + + + + + + + + + + 316 + 14 + 100 + 34 + + + + + + + + + + 316 + 14 + 100 + 34 + + + + + + + + + + 316 + 14 + 100 + 34 + + + + + + + + + + 63 + 31 + 200 + 20 + + + + + + + + + + 0 + 0 + 424 + 162 + + + + + + 63 + 64 + 238 + 85 + + + + + + + + + + 63 + 62 + 238 + 20 + + + + + + + + + + 63 + 86 + 260 + 20 + + + + + + + + + + 63 + 110 + 238 + 20 + + + + + + + + + + 63 + 134 + 238 + 20 + + + + + + + leInfo_1 + leInfo_2 + leInfo_3 + leInfo_4 + btnInfo + + + + + 14 + 14 + 32 + 32 + + + + + + + + + + 2 + 59 + 421 + 2 + + + + background-color: rgba(156, 156, 156,0.1); + + + Qt::Horizontal + + + + + + 0 + 0 + 424 + 60 + + + + + + + 316 + 14 + 100 + 34 + + + + + + + + + + 380 + 20 + 20 + 20 + + + + + + + + + + 316 + 14 + 70 + 34 + + + + + + + wbg + wbg_2 + lbName + lbConned + lbIcon + line + btnConnSub + btnDisConn + btnConn + lbWaiting + lbWaitingIcon + btnCancel + + + + diff --git a/src/frontend/list-items/wlanlistitem.cpp b/src/frontend/list-items/wlanlistitem.cpp new file mode 100644 index 00000000..d0acd7df --- /dev/null +++ b/src/frontend/list-items/wlanlistitem.cpp @@ -0,0 +1,592 @@ +#include "wlanlistitem.h" +#include +#include +#include + +#define EMPTY_SSID "EMPTY_SSID" +#define LOG_FLAG "[WlanListItem]" +#define WAIT_US 10*1000 + +WlanListItem::WlanListItem(KyWirelessNetItem &wirelessNetItem, QString device, bool isApMode, QWidget *parent) + : WlanListItem(wirelessNetItem, device, parent) +{ + m_isApMode = isApMode; + refreshIcon(false); // 额外刷新一次图标,因为WlanListItem执行时,m_isApMode尚未赋值 +} + +WlanListItem::WlanListItem(KyWirelessNetItem &wirelessNetItem, QString device, QWidget *parent) : ListItem(parent) +{ + m_wlanDevice = device; + m_wirelessNetItem = wirelessNetItem; + + qDebug()<<"[WlanPage] wlan list item is created." << m_wirelessNetItem.m_NetSsid; + + initWlanUI(); + setExpanded(false); + + connect(this->m_infoButton, &InfoButton::clicked, this, &WlanListItem::onInfoButtonClicked); + connect(m_menu, &QMenu::triggered, this, &WlanListItem::onMenuTriggered); + + m_wirelessConnectOperation = new KyWirelessConnectOperation(this); +} + +WlanListItem::WlanListItem(QWidget *parent) : ListItem(parent) +{ + m_wirelessNetItem.m_NetSsid = EMPTY_SSID; + + qDebug()<<"[WlanPage] wlan list item is created." << m_wirelessNetItem.m_NetSsid; + + m_netButton->setButtonIcon(QIcon::fromTheme("network-wireless-offline-symbolic")); + m_netButton->setActive(false); +// m_netButton->setDefaultPixmap(); + const QString name = tr("Not connected"); + setExpanded(false); + this->setName(name); +// this->m_netButton->setEnabled(false); + this->m_infoButton->hide(); +} + +WlanListItem::~WlanListItem() +{ + qDebug()<<"[WlanPage] wlan list item is deleted." << m_wirelessNetItem.m_NetSsid; +} + +QString WlanListItem::getSsid() +{ + return m_wirelessNetItem.m_NetSsid; +} + +void WlanListItem::setSignalStrength(const int &signal) +{ + m_wirelessNetItem.m_signalStrength = signal; + if (Activated == m_connectState) { + refreshIcon(true); + } else if (Deactivated == m_connectState) { + refreshIcon(false); + } + + return; +} + +int WlanListItem::getSignalStrength() +{ + return m_wirelessNetItem.m_signalStrength; +} + +bool WlanListItem::isConfigured() +{ + return m_wirelessNetItem.m_isConfigured; +} + +void WlanListItem::setWlanState(const int &state) +{ +// m_wirelessNetItem.m_state = state; //ZJP_TODO 后端接口待补全 + refreshIcon(false); +} + +void WlanListItem::setExpanded(const bool &expanded) +{ + if (!m_pwdFrame || !m_autoConnectFrame) { + this->setFixedHeight(NORMAL_HEIGHT); + return; + } + + m_pwdFrame->setVisible(expanded); + m_autoConnectFrame->setVisible(expanded); + + if (expanded) { + m_pwdLineEdit->setFocus(); + setFixedHeight(EXPANDED_HEIGHT); + } else { + setFixedHeight(NORMAL_HEIGHT); + QPalette pal = qApp->palette(); + pal.setColor(QPalette::Window, qApp->palette().base().color()); + this->setPalette(pal); + } + + emit this->itemHeightChanged(expanded, m_wirelessNetItem.m_NetSsid); + + return; +} + +void WlanListItem::resizeEvent(QResizeEvent *event) +{ + this->blockSignals(true); + + if (this->height() == EXPANDED_HEIGHT) { + this->setExpanded(true); + } else { + this->setExpanded(false); + } + + this->blockSignals(false); + + return ListItem::resizeEvent(event); +} + +void WlanListItem::onRightButtonClicked() +{ + qDebug()<< LOG_FLAG <<"onRightButtonClicked"; + + if (!m_menu) { + return; + } + + m_menu->clear(); + + if (Activated == m_connectState || Activating == m_connectState) { + m_menu->addAction(new QAction(tr("Disconnect"), this)); + } else if (Deactivated == m_connectState) { + m_menu->addAction(new QAction(tr("Connect"), this)); + qDebug() << "add connect action"; + } else { + return; + } + + if (m_wirelessNetItem.m_isConfigured) { + m_menu->addAction(new QAction(tr("Forget"), this)); + } + + m_menu->move(cursor().pos()); + m_menu->show(); + + return; +} + +void WlanListItem::enterEvent(QEvent *event) +{ + //qDebug()<< LOG_FLAG <<"enterEvent" << m_wirelessNetItem.m_NetSsid; + m_mouseIsOut = false; + return ListItem::enterEvent(event); +} + +void WlanListItem::leaveEvent(QEvent *event) +{ + //qDebug()<< LOG_FLAG <<"leaveEvent"<< m_wirelessNetItem.m_NetSsid; + m_mouseIsOut = true; + if (m_pwdFrame && m_pwdFrame->isVisible()) { + if (m_focusIsOut) { + setExpanded(false); + } + return QFrame::leaveEvent(event); + } + + return ListItem::leaveEvent(event); +} + +bool WlanListItem::eventFilter(QObject *watched, QEvent *event) +{ + if (watched == m_showPwdButton || watched == m_autoConnectCheckBox) { + if (event->type() == QEvent::FocusIn) { + m_pwdLineEdit->setFocus(); + } + } + + if (watched == m_pwdLineEdit) { + if (event->type() == QEvent::FocusOut) { + m_focusIsOut = true; + //qDebug()<< LOG_FLAG <<"focusOutEvent" << m_wirelessNetItem.m_NetSsid; + if (m_mouseIsOut) { + setExpanded(false); + } + } else if (event->type() == QEvent::FocusIn) { + //qDebug()<< LOG_FLAG <<"focusInEvent" << m_wirelessNetItem.m_NetSsid; + m_focusIsOut = false; + } + } + + return QFrame::eventFilter(watched, event); +} + +void WlanListItem::keyPressEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) { + if (m_pwdFrame && m_pwdFrame->isVisible() && m_pwdLineEdit->text().length() >= PWD_LENGTH_LIMIT) { + onConnectButtonClicked(); + } + } + return QFrame::keyPressEvent(event); +} + +void WlanListItem::initWlanUI() +{ + m_hasPwd = (m_wirelessNetItem.m_secuType.isEmpty() || m_wirelessNetItem.m_secuType == "") ? false : true; + //设置显示的Wlan名称 +// this->setName((m_wirelessNetItem.m_connName != "") ? m_wirelessNetItem.m_connName : m_wirelessNetItem.m_NetSsid); + this->setName(m_wirelessNetItem.m_NetSsid); + //刷新左侧按钮图标 + refreshIcon(false); + +#define PWD_AREA_HEIGHT 36 +#define CONNECT_BUTTON_WIDTH 96 +#define FRAME_CONTENT_MARGINS 56,0,16,4 +#define FRAME_SPACING 8 +#define LINEEDIT_WIDTH 220 +#define PWD_CONTENT_MARGINS 8,0,34,0 +#define SHOW_PWD_BUTTON_SIZE 24,24 +#define PWD_LAYOUT_MARGINS 8,0,8,0 + //密码输入区域的UI + m_pwdFrame = new QFrame(this); + m_pwdFrameLyt = new QHBoxLayout(m_pwdFrame); + m_pwdFrameLyt->setContentsMargins(FRAME_CONTENT_MARGINS); + m_pwdFrameLyt->setSpacing(FRAME_SPACING); + m_pwdFrame->setLayout(m_pwdFrameLyt); + + m_pwdLineEdit = new QLineEdit(m_pwdFrame); + m_pwdLineEdit->setFixedWidth(LINEEDIT_WIDTH); +// m_pwdLineEdit->setAttribute(Qt::WA_InputMethodEnabled, false); + m_pwdLineEdit->setContextMenuPolicy(Qt::NoContextMenu); + + QRegExp rx("^[A-Za-z0-9`~!@#$%^&*()_-+=<>,.\\\/]+$"); + QRegExpValidator *latitude = new QRegExpValidator(rx, this); + m_pwdLineEdit->setValidator(latitude); + + m_pwdLineEdit->installEventFilter(this); + connect(m_pwdLineEdit, &QLineEdit::textChanged, this, &WlanListItem::onPwdEditorTextChanged); + m_pwdLineEdit->setFixedHeight(PWD_AREA_HEIGHT); + m_pwdLineEdit->setEchoMode(QLineEdit::EchoMode::Password); + m_pwdLineEdit->setTextMargins(PWD_CONTENT_MARGINS); + m_pwdFrameLyt->addWidget(m_pwdLineEdit); + + m_pwdLineEditLyt = new QHBoxLayout(m_pwdLineEdit); + m_pwdLineEditLyt->setContentsMargins(PWD_LAYOUT_MARGINS); + m_pwdLineEdit->setLayout(m_pwdLineEditLyt); + + m_showPwdButton = new QPushButton(m_pwdLineEdit); + m_showPwdButton->setFlat(true); //去除边框 + m_showPwdButton->installEventFilter(this); + m_showPwdButton->setFixedSize(SHOW_PWD_BUTTON_SIZE); + m_showPwdButton->setIcon(QIcon::fromTheme("ukui-eye-hidden-symbolic")); + m_showPwdButton->setCursor(Qt::PointingHandCursor); + connect(m_showPwdButton, &QPushButton::clicked, this, &WlanListItem::onShowPwdButtonClicked); + m_pwdLineEditLyt->addStretch(); + m_pwdLineEditLyt->addWidget(m_showPwdButton); + + m_connectButton = new QPushButton(m_pwdFrame); + m_connectButton->setFixedSize(CONNECT_BUTTON_WIDTH, PWD_AREA_HEIGHT); + m_connectButton->setText(tr("Connect")); + m_connectButton->setEnabled(false); + connect(m_connectButton, &QPushButton::clicked, this, &WlanListItem::onConnectButtonClicked); + m_pwdFrameLyt->addWidget(m_connectButton); + m_pwdFrameLyt->addStretch(); + + //自动连接选择区域UI + m_autoConnectFrame = new QFrame(this); + + m_autoConnectFrameLyt = new QHBoxLayout(m_autoConnectFrame); + m_autoConnectFrameLyt->setContentsMargins(FRAME_CONTENT_MARGINS); + m_autoConnectFrameLyt->setSpacing(FRAME_SPACING); + m_autoConnectFrame->setLayout(m_autoConnectFrameLyt); + + m_autoConnectCheckBox = new QCheckBox(m_autoConnectFrame); + m_autoConnectCheckBox->installEventFilter(this); + m_autoConnectCheckBox->setChecked(true); + m_autoConnectCheckBox->setFixedSize(SHOW_PWD_BUTTON_SIZE); + m_autoConnectFrameLyt->addWidget(m_autoConnectCheckBox); + + m_autoConnectLabel = new QLabel(m_autoConnectFrame); + m_autoConnectLabel->setText(tr("Auto Connect")); + m_autoConnectFrameLyt->addWidget(m_autoConnectLabel); + m_autoConnectFrameLyt->addStretch(); + + m_mainLayout->addWidget(m_pwdFrame); + m_mainLayout->addWidget(m_autoConnectFrame); + + m_pwdFrame->hide(); + m_autoConnectFrame->hide(); +} + +void WlanListItem::refreshIcon(bool isActivated) +{ +#define FULL_SIGNAL 5 +#define EXCELLENT_SIGNAL 4 +#define GOOD_SIGNAL 3 +#define OK_SIGNAL 2 +#define LOW_SIGNAL 1 +#define STEP 25 + if (m_isApMode) { + m_netButton->setButtonIcon(QIcon::fromTheme("network-wireless-hotspot-symbolic", QIcon(":/res/w/wifi-full.png"))); + m_netButton->setActive(isActivated); + return; + } + + if (!m_hasPwd) { + //ZJP_TODO 无加密 注意信号格数计算方式,可能需要修改 + switch (m_wirelessNetItem.m_signalStrength / STEP + 1) { + case FULL_SIGNAL: + case EXCELLENT_SIGNAL: + m_netButton->setButtonIcon(QIcon::fromTheme("network-wireless-signal-excellent-symbolic", + QIcon(":/res/w/wifi-full.png"))); + break; + case GOOD_SIGNAL: + m_netButton->setButtonIcon(QIcon::fromTheme("network-wireless-signal-good-symbolic", + QIcon(":/res/w/wifi-high.png"))); + break; + case OK_SIGNAL: + m_netButton->setButtonIcon(QIcon::fromTheme("network-wireless-signal-ok", + QIcon(":/res/w/wifi-medium.png"))); + break; + case LOW_SIGNAL: + m_netButton->setButtonIcon(QIcon::fromTheme("network-wireless-signal-low", + QIcon(":/res/w/wifi-low.png"))); + break; + default: + qDebug() << "Set wlan(without passwd) icon failed, signal = " + << m_wirelessNetItem.m_signalStrength << Q_FUNC_INFO << __LINE__; + break; + } + } else { + //ZJP_TODO 有加密 + switch (m_wirelessNetItem.m_signalStrength / STEP + 1) { + case FULL_SIGNAL: + case EXCELLENT_SIGNAL: + m_netButton->setButtonIcon(QIcon::fromTheme("network-wireless-signal-excellent-secure-symbolic", + QIcon(":/res/w/wifi-full-pwd.png"))); + break; + case GOOD_SIGNAL: + m_netButton->setButtonIcon(QIcon::fromTheme("network-wireless-signal-good-secure-symbolic", + QIcon(":/res/w/wifi-high-pwd.png"))); + break; + case OK_SIGNAL: + m_netButton->setButtonIcon(QIcon::fromTheme("network-wireless-signal-ok-secure-symbolic", + QIcon(":/res/w/wifi-medium-pwd.png"))); + break; + case LOW_SIGNAL: + m_netButton->setButtonIcon(QIcon::fromTheme("network-wireless-signal-low-secure-symbolic", + QIcon(":/res/w/wifi-low-pwd.png"))); + break; + default: + qDebug() << "Set wlan(with passwd) icon failed, signal = " + << m_wirelessNetItem.m_signalStrength << Q_FUNC_INFO << __LINE__; + break; + } + } + m_netButton->setActive(isActivated); +} + +void WlanListItem::onInfoButtonClicked() +{ + //ZJP_TODO 呼出无线详情页 + if(netDetail != nullptr){ + netDetail->activateWindow(); + return; + } + + qDebug() << LOG_FLAG << "Net active or not:"<< m_connectState; + qDebug() << LOG_FLAG << "On wlan info button clicked! ssid = " + << m_wirelessNetItem.m_NetSsid << "; name = " + << m_wirelessNetItem.m_connName << "." <show(); + emit this->detailShow(true); +} + +void WlanListItem::onNetButtonClicked() +{ + qDebug() << LOG_FLAG << "onNetButtonClicked"; + if (m_wirelessNetItem.m_NetSsid == EMPTY_SSID) { + return; + } + + if (Deactivated != m_connectState) { + qDebug() << LOG_FLAG <<"the connection" << m_wirelessNetItem.m_connName + << "is not deactived, so it can not be operation." << Q_FUNC_INFO << __LINE__; + return; + } + + //有配置或者无密码的wifi直接连接 + if (m_wirelessNetItem.m_isConfigured) { + m_wirelessConnectOperation->activeWirelessConnect(m_wlanDevice, m_wirelessNetItem.m_connectUuid); + qDebug()<<"[WlanListItem] Has configuration, will be activated. ssid = " + << m_wirelessNetItem.m_NetSsid << Q_FUNC_INFO << __LINE__; + m_netButton->startLoading(); + return; + } + + if (!this->m_connectButton->isVisible() && m_wirelessNetItem.m_secuType != "") { + if (m_wirelessNetItem.m_secuType.contains("802.1x", Qt::CaseInsensitive)) { + if (isEnterpriseWlanDialogShow && enterpriseWlanDialog != nullptr) { + qDebug() << LOG_FLAG <<"EnterpriseWlanDialog is show do not show again!"; + KWindowSystem::raiseWindow(enterpriseWlanDialog->winId()); + return; + } else { + enterpriseWlanDialog = new EnterpriseWlanDialog(m_wirelessNetItem, m_wlanDevice, this); + connect(enterpriseWlanDialog, &EnterpriseWlanDialog::enterpriseWlanDialogClose, this, &WlanListItem::onEnterpriseWlanDialogClose); + enterpriseWlanDialog->show(); + isEnterpriseWlanDialogShow = true; + } + } else { + this->setExpanded(true); + } + } else { + onConnectButtonClicked(); + } + + return; +} + +void WlanListItem::updateWirelessNetSecurity(QString ssid, QString securityType) +{ + if (ssid != m_wirelessNetItem.m_NetSsid) { + return; + } + + qDebug() << LOG_FLAG << "Security changed! ssid = " << m_wirelessNetItem.m_NetSsid + << "; security = " << m_wirelessNetItem.m_secuType << "." <text().length() < PWD_LENGTH_LIMIT) { + m_connectButton->setEnabled(false); + } else { + m_connectButton->setEnabled(true); + } + + return; +} + +void WlanListItem::onShowPwdButtonClicked() +{ + qDebug()<< LOG_FLAG << "onShowPwdButtonClicked"; + if (!m_pwdLineEdit) { + return; + } + + if (m_pwdLineEdit->echoMode() == QLineEdit::EchoMode::Password) { + m_showPwdButton->setIcon(QIcon::fromTheme("ukui-eye-display-symbolic")); + m_pwdLineEdit->setEchoMode(QLineEdit::EchoMode::Normal); + } else { + m_showPwdButton->setIcon(QIcon::fromTheme("ukui-eye-hidden-symbolic")); + m_pwdLineEdit->setEchoMode(QLineEdit::EchoMode::Password); + } + + return; +} + +void WlanListItem::onConnectButtonClicked() +{ + qDebug()<< LOG_FLAG << "onConnectButtonClicked"; + if ((Activating == m_connectState || Deactivating == m_connectState)) { + qDebug() << LOG_FLAG << "On wlan clicked! But there is nothing to do because it is already activating/deactivating!" + << Q_FUNC_INFO << __LINE__; + return; + } + + if (m_connectButton->isVisible() && !m_connectButton->isEnabled()) { + qWarning() << "Connect wlan failed because of null pointer or button state!" << Q_FUNC_INFO << __LINE__; + return; + } + + KyWirelessConnectSetting settings; + settings.m_connectName = m_wirelessNetItem.m_NetSsid; + settings.m_ssid = m_wirelessNetItem.m_NetSsid; + settings.isAutoConnect = m_autoConnectCheckBox->isChecked(); + settings.m_psk = m_pwdLineEdit->text(); + if (m_wirelessNetItem.m_secuType.isEmpty() || m_wirelessNetItem.m_secuType == "") { + settings.m_type = WpaNone; + } else if (m_wirelessNetItem.m_secuType.contains("WPA1") || m_wirelessNetItem.m_secuType.contains("WPA2")) { + settings.m_type = WpaPsk; + } else if (m_wirelessNetItem.m_secuType.contains("WPA3")) { + settings.m_type = SAE; + } + + qDebug() << "[WlanListItem] On button connect clicked, will connect wlan. ssid = " + << m_wirelessNetItem.m_NetSsid << Q_FUNC_INFO <<__LINE__; + + m_wirelessConnectOperation->addAndActiveWirelessConnect(m_wlanDevice, settings, false); + setExpanded(false); + m_netButton->startLoading(); + return; +} + +ConnectState WlanListItem::getConnectionState() +{ + return m_connectState; +} + +void WlanListItem::updateConnectState(ConnectState state) +{ + m_connectState = state; + + if (Activated == state) { + m_netButton->stopLoading(); + m_netButton->setActive(true); + } else if(Deactivated == state) { + qDebug() << "[WlanListItem] stop loading connect state:" << state; + m_netButton->stopLoading(); + m_netButton->setActive(false); + } else { + qDebug() << "[WlanListItem] start loading connect state:" << state; + m_netButton->startLoading(); + } + + return; +} + +void WlanListItem::onMenuTriggered(QAction *action) +{ + if (action->text() == tr("Connect")) { + this->onNetButtonClicked(); + } else if (action->text() == tr("Disconnect")) { + m_wirelessConnectOperation->deActivateWirelessConnection(m_wlanDevice, m_wirelessNetItem.m_connectUuid); + qDebug()<<"[WlanListItem] Clicked on connected wifi, it will be inactivated. ssid = " + << m_wirelessNetItem.m_NetSsid << Q_FUNC_INFO << __LINE__; + m_netButton->startLoading(); + } else if (action->text() == tr("Forget")) { + m_wirelessConnectOperation->deleteWirelessConnect(m_wirelessNetItem.m_connectUuid); + } + + return; +} + +void WlanListItem::onEnterpriseWlanDialogClose(bool isShow) +{ + isEnterpriseWlanDialogShow = isShow; + + return; +} + +void WlanListItem::forgetPwd() +{ + if (!this->isConfigured()) { + m_pwdLineEdit->setText(""); + return; + } +} + + diff --git a/src/frontend/list-items/wlanlistitem.h b/src/frontend/list-items/wlanlistitem.h new file mode 100644 index 00000000..641af74e --- /dev/null +++ b/src/frontend/list-items/wlanlistitem.h @@ -0,0 +1,107 @@ +#ifndef WLANLISTITEM_H +#define WLANLISTITEM_H +#include "listitem.h" +#include "kywirelessnetitem.h" +#include "kywirelessnetresource.h" +#include "wlanpage.h" +#include "kywirelessconnectoperation.h" +#include +#include "kylinactiveconnectresource.h" +#include +#include "enterprisewlandialog.h" + +#include + +#define PSK_SETTING_NAME "802-11-wireless-security" + +#define NORMAL_HEIGHT 48 +#define EXPANDED_HEIGHT 120 +#define PWD_LENGTH_LIMIT 8 + +class WlanListItem : public ListItem +{ + Q_OBJECT +public: + WlanListItem(KyWirelessNetItem &wirelessNetItem, QString device, bool isApMode, QWidget *parent = nullptr); + WlanListItem(KyWirelessNetItem &wirelessNetItem, QString device, QWidget *parent = nullptr); + WlanListItem(QWidget *parent = nullptr); + ~WlanListItem(); + +public: + QString getSsid(); + + void setSignalStrength(const int &signal); + int getSignalStrength(); + + bool isConfigured(); + + void setWlanState(const int &state); + void setExpanded(const bool &expanded); + + ConnectState getConnectionState(); + void updateConnectState(ConnectState state); + + void updateWirelessNetSecurity(QString ssid, QString securityType); + void updateWirelessNetItem(KyWirelessNetItem &wirelessNetItem); + + void forgetPwd(); + +protected: + void resizeEvent(QResizeEvent *event); + void onRightButtonClicked(); + void enterEvent(QEvent *event); + void leaveEvent(QEvent *event); + bool eventFilter(QObject *watched, QEvent *event); + void keyPressEvent(QKeyEvent *event); + +signals: + void itemHeightChanged(const bool isExpanded, const QString &ssid); + +private: + void initWlanUI(); + void refreshIcon(bool isActivated); + +private: + KyWirelessNetItem m_wirelessNetItem; + KyWirelessConnectOperation *m_wirelessConnectOperation = nullptr; + EnterpriseWlanDialog *enterpriseWlanDialog = nullptr; + + bool m_hasPwd = true; + QString m_wlanDevice; + + bool isEnterpriseWlanDialogShow = false; + + //密码输入区域的UI + QFrame *m_pwdFrame = nullptr; + QHBoxLayout *m_pwdFrameLyt = nullptr; + + QLineEdit * m_pwdLineEdit = nullptr; + QHBoxLayout *m_pwdLineEditLyt = nullptr; + QPushButton *m_showPwdButton = nullptr; + QPushButton *m_connectButton = nullptr; + + //自动连接选择区域UI + QFrame *m_autoConnectFrame = nullptr; + QHBoxLayout *m_autoConnectFrameLyt = nullptr; + QCheckBox *m_autoConnectCheckBox = nullptr; + QLabel *m_autoConnectLabel = nullptr; + + bool m_focusIsOut = true; + bool m_mouseIsOut = true; + + bool m_forgetConnection = false; + bool m_isApMode = false; + +protected slots: + void onInfoButtonClicked(); + +private slots: + void onNetButtonClicked(); + void onPwdEditorTextChanged(); + void onShowPwdButtonClicked(); + void onConnectButtonClicked(); + void onMenuTriggered(QAction *action); + void onEnterpriseWlanDialogClose(bool isShow); +}; + +#endif // WLANLISTITEM_H diff --git a/src/frontend/list-items/wlanmoreitem.cpp b/src/frontend/list-items/wlanmoreitem.cpp new file mode 100644 index 00000000..7284d703 --- /dev/null +++ b/src/frontend/list-items/wlanmoreitem.cpp @@ -0,0 +1,25 @@ +#include "wlanmoreitem.h" + +WlanMoreItem::WlanMoreItem(QWidget *parent) : ListItem(parent) +{ + setObjectName(WMI_OB_NAME); + m_netButton->setVisible(false); + m_infoButton->setVisible(false); + m_nameLabel->setText(tr("Add Others...")); +} + +WlanMoreItem::~WlanMoreItem() { + +} + +void WlanMoreItem::onNetButtonClicked() { + emit hiddenWlanClicked(); +} + +void WlanMoreItem::onRightButtonClicked() { + // Todo +} + +void WlanMoreItem::onMenuTriggered(QAction *action) { + +} diff --git a/src/frontend/list-items/wlanmoreitem.h b/src/frontend/list-items/wlanmoreitem.h new file mode 100644 index 00000000..52183403 --- /dev/null +++ b/src/frontend/list-items/wlanmoreitem.h @@ -0,0 +1,26 @@ +#ifndef WLANMOREITEM_H +#define WLANMOREITEM_H + +#include +#include "listitem.h" + +const QString WMI_OB_NAME = "WlanMoreItemObjName"; + +class WlanMoreItem : public ListItem +{ + Q_OBJECT + +protected: + void onRightButtonClicked(); + +public: + WlanMoreItem(QWidget *parent = nullptr); + ~WlanMoreItem(); + + void onNetButtonClicked(); + void onMenuTriggered(QAction *action); +signals: + void hiddenWlanClicked(); +}; + +#endif // WLANMOREITEM_H diff --git a/src/frontend/mainwindow.cpp b/src/frontend/mainwindow.cpp new file mode 100644 index 00000000..1372a8ff --- /dev/null +++ b/src/frontend/mainwindow.cpp @@ -0,0 +1,789 @@ +#include "mainwindow.h" +#include "customstyle.h" +#include +#include +#include +#include +#include +#include + +#include "kylinnetworkdeviceresource.h" +#include "../backend/dbus-interface/kylinagentinterface.h" + + +#define MAINWINDOW_WIDTH 420 +#define MAINWINDOW_HEIGHT 476 +#define LAYOUT_MARGINS 0,0,0,0 +#define LOADING_TRAYICON_TIMER_MS 60 +#define THEME_SCHAME "org.ukui.style" +#define COLOR_THEME "styleName" + +const QString v10Sp1 = "V10SP1"; +const QString intel = "V10SP1-edu"; + +#define KEY_PRODUCT_FEATURES "PRODUCT_FEATURES" + +#include +#include + +MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) +{ + firstlyStart(); +} + +/** + * @brief MainWindow::showMainwindow show主窗口,同时也作为dbus接口提供给外部组件调用 + */ +void MainWindow::showMainwindow() +{ + if (!m_loadFinished) { + m_secondaryStartTimer->stop(); + secondaryStart(); + } + + /** + * 设置主界面跳过任务栏和分页器的属性,隐藏再次展示有可能辉冲刷掉该属性,需要展示时重新设置 + */ + const KWindowInfo info(this->winId(), NET::WMState); + if (!info.hasState(NET::SkipTaskbar) || !info.hasState(NET::SkipPager)) { + KWindowSystem::setState(this->winId(), NET::SkipTaskbar | NET::SkipPager); + } + + this->resetWindowPosition(); + this->showNormal(); + this->raise(); + this->activateWindow(); + emit this->mainWindowVisibleChanged(true); +#ifdef WITHKYSEC + if (!kysec_is_disabled() && kysec_get_3adm_status() && (getuid() || geteuid())){ + if (nullptr != m_wlanWidget) { + m_wlanWidget->hideSetting(); + } + if (nullptr != m_lanWidget) { + m_lanWidget->hideSetting(); + } + } else { + if (nullptr != m_wlanWidget) { + m_wlanWidget->showSetting(); + } + if (nullptr != m_lanWidget) { + m_lanWidget->showSetting(); + } + } +#endif + +} + +/** + * @brief MainWindow::hideMainwindow 隐藏主页面时要进行的操作,后续可以添加到此函数 + */ +void MainWindow::hideMainwindow() +{ + this->hide(); + emit this->mainWindowVisibleChanged(false); +} + +/** + * @brief MainWindow::setWiredDefaultDevice 设置有线设备默认网卡 + */ +void MainWindow::setWiredDefaultDevice(QString deviceName) +{ +// m_lanWidget->updateDefaultDevice(deviceName); +} + +/** + * @brief MainWindow::hideMainwindow 设置无线设备默认网卡 + */ +void MainWindow::setWirelessDefaultDevice(QString deviceName) +{ +// m_wlanWidget->updateDefaultDevice(deviceName); +} + +/** + * @brief MainWindow::firstlyStart 一级启动,执行重要且不耗时的启动操作 + */ +void MainWindow::firstlyStart() +{ + initWindowProperties(); + initTransparency(); + initUI(); + initDbusConnnect(); + initWindowTheme(); + initTrayIcon(); + initPlatform(); + installEventFilter(this); + m_secondaryStartTimer = new QTimer(this); + connect(m_secondaryStartTimer, &QTimer::timeout, this, [ = ]() { + m_secondaryStartTimer->stop(); + secondaryStart();//满足条件后执行比较耗时的二级启动 + }); + m_secondaryStartTimer->start(5 * 1000); + + m_createPagePtrMap.clear(); + + //加载key ring + agent_init(); +} + +/** + * @brief MainWindow::secondaryStart 二级启动,可以将较耗时的初始化操作放到此处执行 + */ +void MainWindow::secondaryStart() +{ + if (m_loadFinished) + return; + m_loadFinished = true; +} + +/** + * @brief MainWindow::initWindowProperties 初始化平台信息 + */ +void MainWindow::initPlatform() +{ + if(v10Sp1.compare(KDKGetPrjCodeName().c_str(),Qt::CaseInsensitive) == 0) { + QString feature = KDKGetOSRelease(KEY_PRODUCT_FEATURES).c_str(); + if (feature.toInt() == 3) { + m_isShowInCenter = true; + } + } else if (intel.compare(KDKGetPrjCodeName().c_str(),Qt::CaseInsensitive) == 0) { + m_isShowInCenter = true; + } + + qDebug() << KDKGetPrjCodeName().c_str() << KDKGetOSRelease(KEY_PRODUCT_FEATURES).c_str() << "m_isShowInCenter" << m_isShowInCenter; +} + +/** + * @brief MainWindow::initWindowProperties 初始化一些窗口属性 + */ +void MainWindow::initWindowProperties() +{ + this->setWindowTitle(tr("kylin-nm")); + this->setWindowIcon(QIcon::fromTheme("kylin-network", QIcon(":/res/x/setup.png"))); + this->setFixedSize(MAINWINDOW_WIDTH, MAINWINDOW_HEIGHT); +// //绘制毛玻璃特效 + this->setAttribute(Qt::WA_TranslucentBackground, true); //透明 + this->setFocusPolicy(Qt::NoFocus); + + QPainterPath path; + auto rect = this->rect(); + path.addRoundedRect(rect, 12, 12); + KWindowEffects::enableBlurBehind(this->winId(), true, QRegion(path.toFillPolygon().toPolygon())); //背景模糊 +} + +void MainWindow::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); // 反锯齿; + painter.setPen(Qt::transparent); + auto rect = this->rect(); + painter.drawRoundedRect(rect, 12, 12); //窗口圆角 +} + +void MainWindow::initTransparency() +{ + if(QGSettings::isSchemaInstalled(TRANSPARENCY_GSETTINGS)) { + m_transGsettings = new QGSettings(TRANSPARENCY_GSETTINGS); + if(m_transGsettings->keys().contains(QString("transparency"))) { + m_transparency=m_transGsettings->get("transparency").toDouble() + 0.15; + m_transparency = (m_transparency > 1) ? 1 : m_transparency; + connect(m_transGsettings, &QGSettings::changed, this, &MainWindow::onTransChanged); + } + } +} + +void MainWindow::onTransChanged() +{ + m_transparency = m_transGsettings->get("transparency").toDouble() + 0.15; + m_transparency = (m_transparency > 1) ? 1 : m_transparency; + paintWithTrans(); +} + +void MainWindow::paintWithTrans() +{ + QPalette pal = m_centralWidget->palette(); + QColor color = qApp->palette().base().color(); + color.setAlphaF(m_transparency); + pal.setColor(QPalette::Base, color); + m_centralWidget->setPalette(pal); + + QPalette tabPal = m_centralWidget->tabBar()->palette(); + tabPal.setColor(QPalette::Base, color); + + QColor inactiveColor = qApp->palette().window().color(); + inactiveColor.setAlphaF(0.86 *m_transparency); + tabPal.setColor(QPalette::Window, inactiveColor); + + m_centralWidget->tabBar()->setPalette(tabPal); +} + +/** + * @brief MainWindow::initUI 初始化窗口内控件 + */ +void MainWindow::initUI() +{ + m_centralWidget = new QTabWidget(this); + this->setCentralWidget(m_centralWidget); + m_centralWidget->tabBar()->setFixedWidth(this->width()+1); +// m_centralWidget->tabBar()->setStyleSheet("QTabBar::tab{min-height:40px}"); + m_lanWidget = new LanPage(m_centralWidget); + m_wlanWidget = new WlanPage(m_centralWidget); + connect(this, &MainWindow::mainWindowVisibleChanged, m_wlanWidget, &WlanPage::onMainWindowVisibleChanged); +// m_centralWidget->addTab(m_lanWidget, QIcon::fromTheme("network-wired-connected-symbolic", QIcon::fromTheme("network-wired-symbolic", QIcon(":/res/l/network-online.svg"))), tr("LAN")); +// m_centralWidget->addTab(m_wlanWidget, QIcon::fromTheme("network-wireless-signal-excellent-symbolic", QIcon(":/res/x/wifi-list-bg.svg")), tr("WLAN")); + + m_centralWidget->addTab(m_lanWidget, tr("")); + m_centralWidget->addTab(m_wlanWidget,tr("")); + m_tabBarLayout = new QHBoxLayout(this); + m_tabBarLayout->setContentsMargins(LAYOUT_MARGINS); + m_lanLabel = new QLabel(tr("LAN")); + m_lanLabel->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter); + m_wlanLabel = new QLabel(tr("WLAN")); + m_wlanLabel->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter); + m_tabBarLayout->addWidget(m_lanLabel); + m_tabBarLayout->addWidget(m_wlanLabel); + m_centralWidget->tabBar()->setLayout(m_tabBarLayout); + m_centralWidget->tabBar()->setProperty("useTabbarSeparateLine", false); // 去掉中间的分割线 + m_centralWidget->setAttribute(Qt::WA_TranslucentBackground, true); // 背景透明 解决切换黑屏问题 + connect(m_centralWidget, &QTabWidget::currentChanged, m_wlanWidget, &WlanPage::onWlanPageVisibleChanged); + paintWithTrans(); +} + +/** + * @brief MainWindow::initTrayIcon 初始化托盘图标和托盘右键菜单 + */ +void MainWindow::initTrayIcon() +{ + loadIcons.append(QIcon::fromTheme("kylin-network-1")); + loadIcons.append(QIcon::fromTheme("kylin-network-2")); + loadIcons.append(QIcon::fromTheme("kylin-network-3")); + loadIcons.append(QIcon::fromTheme("kylin-network-4")); + loadIcons.append(QIcon::fromTheme("kylin-network-5")); + loadIcons.append(QIcon::fromTheme("kylin-network-6")); + loadIcons.append(QIcon::fromTheme("kylin-network-7")); + loadIcons.append(QIcon::fromTheme("kylin-network-8")); + loadIcons.append(QIcon::fromTheme("kylin-network-9")); + loadIcons.append(QIcon::fromTheme("kylin-network-10")); + loadIcons.append(QIcon::fromTheme("kylin-network-11")); + loadIcons.append(QIcon::fromTheme("kylin-network-12")); + iconTimer = new QTimer(this); + connect(iconTimer, &QTimer::timeout, this, &MainWindow::onSetTrayIconLoading); + + m_trayIcon = new QSystemTrayIcon(); + m_trayIconMenu = new QMenu(); + m_showMainwindowAction = new QAction(tr("Show MainWindow"),this); + m_showSettingsAction = new QAction(tr("Settings"),this); + + m_trayIcon->setToolTip(QString(tr("kylin-nm"))); + m_showSettingsAction->setIcon(QIcon::fromTheme("document-page-setup-symbolic", QIcon(":/res/x/setup.png")) ); +// m_trayIconMenu->addAction(m_showMainwindowAction); + m_trayIconMenu->addAction(m_showSettingsAction); + m_trayIcon->setContextMenu(m_trayIconMenu); + m_trayIcon->setIcon(QIcon::fromTheme("network-wired-signal-excellent-symbolic")); + iconStatus = IconActiveType::LAN_CONNECTED; + onRefreshTrayIcon(); + + connect(m_trayIcon, &QSystemTrayIcon::activated, this, &MainWindow::onTrayIconActivated); +// connect(m_showMainwindowAction, &QAction::triggered, this, &MainWindow::onShowMainwindowActionTriggled); + connect(m_showSettingsAction, &QAction::triggered, this, &MainWindow::onShowSettingsActionTriggled); + m_trayIcon->show(); +} + +void MainWindow::initDbusConnnect() +{ + connect(m_lanWidget, &LanPage::deviceStatusChanged, this, &MainWindow::deviceStatusChanged); + connect(m_lanWidget, &LanPage::deviceNameChanged, this, &MainWindow::deviceNameChanged); + connect(m_wlanWidget, &WlanPage::deviceStatusChanged, this, &MainWindow::deviceStatusChanged); + connect(m_wlanWidget, &WlanPage::deviceNameChanged, this, &MainWindow::deviceNameChanged); + + connect(m_wlanWidget, &WlanPage::activateFailed, this, &MainWindow::activateFailed); + connect(m_wlanWidget, &WlanPage::deactivateFailed, this, &MainWindow::deactivateFailed); + connect(m_lanWidget, &LanPage::activateFailed, this, &MainWindow::activateFailed); + connect(m_lanWidget, &LanPage::deactivateFailed, this, &MainWindow::deactivateFailed); + + connect(m_lanWidget, &LanPage::lanAdd, this, &MainWindow::lanAdd); + connect(m_lanWidget, &LanPage::lanRemove, this, &MainWindow::lanRemove); + connect(m_lanWidget, &LanPage::lanUpdate, this, &MainWindow::lanUpdate); + connect(m_lanWidget, &LanPage::lanActiveConnectionStateChanged, this, &MainWindow::lanActiveConnectionStateChanged); + connect(m_lanWidget, &LanPage::lanConnectChanged, this, &MainWindow::onLanConnectStatusToChangeTrayIcon); + + + connect(m_wlanWidget, &WlanPage::wlanAdd, this, &MainWindow::wlanAdd); + connect(m_wlanWidget, &WlanPage::wlanRemove, this, &MainWindow::wlanRemove); + connect(m_wlanWidget, &WlanPage::wlanActiveConnectionStateChanged, this, &MainWindow::wlanactiveConnectionStateChanged); + connect(m_wlanWidget, &WlanPage::wlanConnectChanged, this, &MainWindow::onWlanConnectStatusToChangeTrayIcon); + connect(m_wlanWidget, &WlanPage::hotspotDeactivated, this, &MainWindow::hotspotDeactivated); + connect(m_wlanWidget, &WlanPage::hotspotActivated, this, &MainWindow::hotspotActivated); + connect(m_wlanWidget, &WlanPage::secuTypeChange, this, &MainWindow::secuTypeChange); + connect(m_wlanWidget, &WlanPage::signalStrengthChange, this, &MainWindow::signalStrengthChange); + connect(m_wlanWidget, &WlanPage::timeToUpdate , this, &MainWindow::timeToUpdate); + connect(m_wlanWidget, &WlanPage::showMainWindow, this, &MainWindow::onShowMainWindow); + connect(m_wlanWidget, &WlanPage::connectivityChanged, this, &MainWindow::onConnectivityChanged); + + //模式切换 + QDBusConnection::sessionBus().connect(QString("com.kylin.statusmanager.interfacer"), + QString("/"), + QString("com.kylin.statusmanager.interface"), + QString("mode_change_signal"), this, SLOT(onTabletModeChanged(bool))); +} + +/** + * @brief MainWindow::resetWindowPosition 重新计算窗口位置 + */ +void MainWindow::resetWindowPosition() +{ + + if (m_isShowInCenter) { + QRect availableGeometry = qApp->primaryScreen()->availableGeometry(); + this->move((availableGeometry.width() - this->width())/2, (availableGeometry.height() - this->height())/2); + return; + } + +#define MARGIN 4 +#define PANEL_TOP 1 +#define PANEL_LEFT 2 +#define PANEL_RIGHT 3 +//#define PANEL_BOTTOM 4 + if (!m_positionInterface) { + m_positionInterface = new QDBusInterface("org.ukui.panel", + "/panel/position", + "org.ukui.panel", + QDBusConnection::sessionBus()); + } + QDBusReply reply = m_positionInterface->call("GetPrimaryScreenGeometry"); + //reply获取的参数共5个,分别是 主屏可用区域的起点x坐标,主屏可用区域的起点y坐标,主屏可用区域的宽度,主屏可用区域高度,任务栏位置 + if (!m_positionInterface->isValid() || !reply.isValid() || reply.value().size() < 5) { + qCritical() << QDBusConnection::sessionBus().lastError().message(); + this->setGeometry(0, 0, this->width(), this->height()); + return; + } + QVariantList position_list = reply.value(); + int position = position_list.at(4).toInt(); + switch(position){ + case PANEL_TOP: + //任务栏位于上方 + this->setGeometry(position_list.at(0).toInt() + position_list.at(2).toInt() - this->width() - MARGIN, + position_list.at(1).toInt() + MARGIN, + this->width(), this->height()); + break; + //任务栏位于左边 + case PANEL_LEFT: + this->setGeometry(position_list.at(0).toInt() + MARGIN, + position_list.at(1).toInt() + reply.value().at(3).toInt() - this->height() - MARGIN, + this->width(), this->height()); + break; + //任务栏位于右边 + case PANEL_RIGHT: + this->setGeometry(position_list.at(0).toInt() + position_list.at(2).toInt() - this->width() - MARGIN, + position_list.at(1).toInt() + reply.value().at(3).toInt() - this->height() - MARGIN, + this->width(), this->height()); + break; + //任务栏位于下方 + default: + this->setGeometry(position_list.at(0).toInt() + position_list.at(2).toInt() - this->width() - MARGIN, + position_list.at(1).toInt() + reply.value().at(3).toInt() - this->height() - MARGIN, + this->width(), this->height()); + break; + } + qDebug() << " Position of ukui-panel is " << position << "; Position of mainwindow is " << this->geometry() << "." << Q_FUNC_INFO << __LINE__; +} + +/** + * @brief MainWindow::resetTrayIconTool 重新获取网络连接状态并重新设置图标和tooltip + */ +void MainWindow::resetTrayIconTool() +{ + //ZJP_TODO 检测当前连接的是有线还是无线,是否可用,设置图标和tooltip,图标最好提前define +// int connectivity = objKyDBus->getNetworkConectivity(); +// qDebug() << "Value of current network Connectivity property : "<< connectivity; +// switch (connectivity) { +// case UnknownConnectivity: +// case Portal: +// case Limited: +// setTrayIcon(iconLanOnlineNoInternet); +// trayIcon->setToolTip(QString(tr("Network Connected But Can Not Access Internet"))); +// break; +// case NoConnectivity: +// case Full: +// setTrayIcon(iconLanOnline); +// trayIcon->setToolTip(QString(tr("kylin-nm"))); +// break; +// } + qDebug() << "Has set tray icon to be XXX." << Q_FUNC_INFO << __LINE__; +} + + +/** + * @brief MainWindow::initWindowTheme 初始化窗口主题并创建信号槽 + */ +void MainWindow::initWindowTheme() +{ + const QByteArray style_id(THEME_SCHAME); + if (QGSettings::isSchemaInstalled(style_id)) { + m_styleGsettings = new QGSettings(style_id); +// resetWindowTheme(); + connect(m_styleGsettings, &QGSettings::changed, this, &MainWindow::onThemeChanged); + } else { + qWarning() << "Gsettings interface \"org.ukui.style\" is not exist!" << Q_FUNC_INFO << __LINE__; + } +} + +/** + * @brief MainWindow::resetWindowTheme 读取和设置窗口主题 + */ +void MainWindow::resetWindowTheme() +{ + if (!m_styleGsettings) { return; } + QString currentTheme = m_styleGsettings->get(COLOR_THEME).toString(); + auto app = static_cast(QCoreApplication::instance()); + if(currentTheme == "ukui-dark" || currentTheme == "ukui-black"){ + app->setStyle(new CustomStyle("ukui-dark")); + qDebug() << "Has set color theme to ukui-dark." << Q_FUNC_INFO << __LINE__; + emit qApp->paletteChanged(qApp->palette()); + return; + } + app->setStyle(new CustomStyle("ukui-light")); + qDebug() << "Has set color theme to " << currentTheme << Q_FUNC_INFO << __LINE__; + emit qApp->paletteChanged(qApp->palette()); + return; +} + +/** + * @brief MainWindow::showControlCenter 打开控制面板网络界面 + */ +void MainWindow::showControlCenter() +{ + QProcess process; + if (!m_lanWidget->lanIsConnected() && m_wlanWidget->checkWlanStatus(NetworkManager::ActiveConnection::State::Activated)){ + process.startDetached("ukui-control-center -m wlanconnect"); + } else { + process.startDetached("ukui-control-center -m netconnect"); + } +} + +/** + * @brief MainWindow::onTrayIconActivated 点击托盘图标的槽函数 + */ +void MainWindow::onTrayIconActivated(QSystemTrayIcon::ActivationReason reason) +{ + if (reason == QSystemTrayIcon::ActivationReason::Context) { + m_trayIconMenu->popup(QCursor::pos()); + } else { + if (this->isVisible()) { + qDebug() << "Received signal of tray icon activated, will hide mainwindow." << Q_FUNC_INFO << __LINE__; + hideMainwindow(); + return; + } + qDebug() << "Received signal of tray icon activated, will show mainwindow." << Q_FUNC_INFO << __LINE__; + this->showMainwindow(); + } +} + +void MainWindow::onShowMainwindowActionTriggled() +{ + showMainwindow(); +} + +void MainWindow::onShowSettingsActionTriggled() +{ + showControlCenter(); +} + +void MainWindow::onThemeChanged(const QString &key) +{ + if (key == COLOR_THEME) { + qDebug() << "Received signal of theme changed, will reset theme." << Q_FUNC_INFO << __LINE__; +// resetWindowTheme(); + paintWithTrans(); + emit qApp->paletteChanged(qApp->palette()); + } else { + qDebug() << "Received signal of theme changed, key=" << key << " will do nothing." << Q_FUNC_INFO << __LINE__; + } +} + +void MainWindow::onRefreshTrayIcon() +{ + //更新托盘图标显示 + iconTimer->stop(); + if (m_lanWidget->lanIsConnected()) { + m_trayIcon->setIcon(QIcon::fromTheme("network-wired-connected-symbolic")); + iconStatus = IconActiveType::LAN_CONNECTED; + } else if (m_wlanWidget->checkWlanStatus(NetworkManager::ActiveConnection::State::Activated)){ + m_trayIcon->setIcon(QIcon::fromTheme("network-wireless-connected-symbolic")); + iconStatus = IconActiveType::WLAN_CONNECTED; + } else { + m_trayIcon->setIcon(QIcon::fromTheme("network-wired-disconnected-symbolic")); + iconStatus = IconActiveType::NOT_CONNECTED; + } + + NetworkManager::Connectivity connecttivity; + m_wlanWidget->getConnectivity(connecttivity); + if (connecttivity != NetworkManager::Connectivity::Full) { + if (iconStatus == IconActiveType::LAN_CONNECTED) { + m_trayIcon->setIcon(QIcon::fromTheme("network-error-symbolic")); + iconStatus = IconActiveType::LAN_CONNECTED_LIMITED; + } else if (iconStatus == IconActiveType::WLAN_CONNECTED) { + //todo 信号强度 + m_trayIcon->setIcon(QIcon::fromTheme("network-wireless-signal-excellent-error-symbolic")); + iconStatus = IconActiveType::WLAN_CONNECTED_LIMITED; + } + } +} + +void MainWindow::onSetTrayIconLoading() +{ + if (currentIconIndex > 11) { + currentIconIndex = 0; + } + m_trayIcon->setIcon(loadIcons.at(currentIconIndex)); + iconStatus = IconActiveType::ACTIVATING; + currentIconIndex ++; +} + +void MainWindow::onLanConnectStatusToChangeTrayIcon(int state) +{ + qDebug() << "lan state:" << state << Q_FUNC_INFO << __LINE__; + if (state==1 || state==3){ + m_lanIsLoading = true; + iconTimer->start(LOADING_TRAYICON_TIMER_MS); + } else { + m_lanIsLoading = false; + if (m_wlanIsLoading == false) { + onRefreshTrayIcon(); + } + } +} + +void MainWindow::onWlanConnectStatusToChangeTrayIcon(int state) +{ + qDebug() << "wlan state:" << state << Q_FUNC_INFO << __LINE__; + if (state==1 || state==3){ + m_wlanIsLoading = true; + iconTimer->start(LOADING_TRAYICON_TIMER_MS); + } else { + if (m_wlanWidget->checkWlanStatus(NetworkManager::ActiveConnection::State::Activating)) { + return; + } + m_wlanIsLoading = false; + if (m_lanIsLoading == false) { + onRefreshTrayIcon(); + } + } +} + +void MainWindow::onTabletModeChanged(bool mode) +{ + qDebug() << "TabletMode change" << mode; + Q_UNUSED(mode) + //模式切换时,隐藏主界面 + hideMainwindow(); +} + +void MainWindow::onShowMainWindow(int type) +{ + m_centralWidget->setCurrentIndex(type); + + if(QApplication::activeWindow() != this) { + this->showMainwindow(); + } +} + +void MainWindow::onConnectivityChanged(NetworkManager::Connectivity connectivity) +{ + if (!m_trayIcon) { + return; + } + + if (iconStatus == ACTIVATING) { + return; + } + + onRefreshTrayIcon(); +} + +/** + * @brief MainWindow::keyPressEvent 按esc键关闭主界面 + * @param event + */ +void MainWindow::keyPressEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_Escape) { + hideMainwindow(); + } + return QWidget::keyPressEvent(event); +} + +/** + * @brief MainWindow::eventFilter 事件过滤器 + * @param watched + * @param event + * @return + */ +bool MainWindow::eventFilter(QObject *watched, QEvent *event) +{ + if (event->type() == QEvent::ActivationChange) { + if(QApplication::activeWindow() != this) { + hideMainwindow(); + } + } + return QMainWindow::eventFilter(watched,event); +} + +/** + * @brief MainWindow::getWirelessList 获取wifi列表,供dbus调用 + * @param map + */ +void MainWindow::getWirelessList(QMap > &map) +{ + map.clear(); + if (nullptr != m_wlanWidget) { + m_wlanWidget->getWirelessList(map); + } +} + +/** + * @brief MainWindow::getWiredList 获取lan列表,供dbus调用 + * @param map + */ +void MainWindow::getWiredList(QMap> &map) +{ + map.clear(); + if (nullptr != m_lanWidget) { + m_lanWidget->getWiredList(map); + } +} + +/** + * @brief MainWindow::activeWirelessAp 开启热点,供dbus调用 + * @param apName + * @param apPassword + * @param apDevice + */ +void MainWindow::activeWirelessAp(const QString apName, const QString apPassword, const QString band, const QString apDevice) +{ + m_wlanWidget->activeWirelessAp(apName, apPassword, band, apDevice); +} + +/** + * @brief MainWindow::activeWirelessAp 断开热点,供dbus调用 + * @param apName + */ +void MainWindow::deactiveWirelessAp(const QString apName, const QString uuid) +{ + m_wlanWidget->deactiveWirelessAp(apName, uuid); +} + +/** + * @brief MainWindow::activeWirelessAp 获取热点,供dbus调用 + * @param list + */ +void MainWindow::getApInfoBySsid(QString devName, QString ssid, QStringList &list) +{ + m_wlanWidget->getApInfoBySsid(devName, ssid, list); +} + +void MainWindow::getStoredApInfo(QStringList &list) +{ + m_wlanWidget->getStoredApInfo(list); +} + +//无线开关 +void MainWindow::setWirelessSwitchEnable(bool enable) +{ + m_wlanWidget->setWirelessSwitchEnable(enable); +} + +void MainWindow::setWiredDeviceEnable(const QString& devName, bool enable) +{ + m_lanWidget->setWiredDeviceEnable(devName, enable); +} +void MainWindow::showPropertyWidget(QString devName, QString ssid) +{ + KyNetworkDeviceResourse *devResourse = new KyNetworkDeviceResourse(); + QStringList wiredDeviceList; + wiredDeviceList.clear(); + devResourse->getNetworkDeviceList(NetworkManager::Device::Type::Ethernet, wiredDeviceList); + if (wiredDeviceList.contains(devName)) { + qDebug() << "showPropertyWidget device type wired device name " << devName << " uuid " << ssid; + m_lanWidget->showDetailPage(devName, ssid); + delete devResourse; + devResourse = nullptr; + return; + } + + QStringList wirelessDeviceList; + wirelessDeviceList.clear(); + devResourse->getNetworkDeviceList(NetworkManager::Device::Type::Wifi, wirelessDeviceList); + if (wirelessDeviceList.contains(devName)) { + qDebug() << "showPropertyWidget device type wireless device name " << devName << " ssid " << ssid; + m_wlanWidget->showDetailPage(devName, ssid); + delete devResourse; + devResourse = nullptr; + return; + } + + qWarning() << "showPropertyWidget no such device " << devName; + delete devResourse; + devResourse = nullptr; +} + +void MainWindow::showCreateWiredConnectWidget(const QString devName) +{ + qDebug() << "showCreateWiredConnectWidget! devName = " << devName; + if (m_createPagePtrMap.contains(devName)) { + if (m_createPagePtrMap[devName] != nullptr) { + qDebug() << "showCreateWiredConnectWidget" << devName << "already create,just raise"; + + KWindowSystem::raiseWindow(m_createPagePtrMap[devName]->winId()); + return; + } + } + NetDetail *netDetail = new NetDetail(devName, "", "", false, false, true, this); + connect(netDetail, &NetDetail::createPageClose, [&](QString interfaceName){ + if (m_createPagePtrMap.contains(interfaceName)) { + m_createPagePtrMap[interfaceName] = nullptr; + } + }); + m_createPagePtrMap.insert(devName, netDetail); + netDetail->show(); +} + +void MainWindow::getWirelessDeviceCap(QMap &map) +{ + m_wlanWidget->getWirelessDeviceCap(map); +} + +//有线连接断开 +void MainWindow::activateWired(const QString& devName, const QString& connUuid) +{ + m_lanWidget->activateWired(devName, connUuid); +} +void MainWindow::deactivateWired(const QString& devName, const QString& connUuid) +{ + m_lanWidget->deactivateWired(devName, connUuid); +} + +//无线连接断开 +void MainWindow::activateWireless(const QString& devName, const QString& ssid) +{ + m_wlanWidget->activateWirelessConnection(devName, ssid); +} + +void MainWindow::deactivateWireless(const QString& devName, const QString& ssid) +{ + m_wlanWidget->deactivateWirelessConnection(devName, ssid); +} + +void MainWindow::rescan() +{ + m_wlanWidget->requestScan(); +} + +void MainWindow::keyRingInit() +{ + agent_init(); +} + +void MainWindow::keyRingClear() +{ + agent_clear(); +} diff --git a/src/frontend/mainwindow.h b/src/frontend/mainwindow.h new file mode 100644 index 00000000..95ccf4a6 --- /dev/null +++ b/src/frontend/mainwindow.h @@ -0,0 +1,183 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lanpage.h" +#include "wlanpage.h" +#include "netdetails/netdetail.h" +#include + +#ifdef WITHKYSEC +#include +#include +#endif + +enum IconActiveType { + NOT_CONNECTED = 0, + LAN_CONNECTED, + WLAN_CONNECTED, + LAN_CONNECTED_LIMITED, + WLAN_CONNECTED_LIMITED, + ACTIVATING, +}; + +const QByteArray TRANSPARENCY_GSETTINGS = "org.ukui.control-center.personalise"; + +class LanPage; + +class MainWindow : public QMainWindow +{ + Q_OBJECT +public: + explicit MainWindow(QWidget *parent = nullptr); + void showMainwindow(); + void hideMainwindow(); + + void setWiredDefaultDevice(QString deviceName); + void setWirelessDefaultDevice(QString deviceName); + + //for dbus + void getWirelessList(QMap > &map); + void getWiredList(QMap> &map); + //开启热点 + void activeWirelessAp(const QString apName, const QString apPassword, const QString wirelessBand, const QString apDevice); + //断开热点 + void deactiveWirelessAp(const QString apName, const QString uuid); + //获取热点 + void getStoredApInfo(QStringList &list); + void getApInfoBySsid(QString devName, QString ssid, QStringList &list); + //有线连接断开 + void activateWired(const QString& devName, const QString& connUuid); + void deactivateWired(const QString& devName, const QString& connUuid); + //无线连接断开 + void activateWireless(const QString& devName, const QString& ssid); + void deactivateWireless(const QString& devName, const QString& ssid); + //无线总开关 + void setWirelessSwitchEnable(bool enable); + + void setWiredDeviceEnable(const QString& devName, bool enable); + + //唤起属性页 根据网卡类型 参数2 为ssid/uuid + void showPropertyWidget(QString devName, QString ssid); + //唤起新建有线连接界面 + void showCreateWiredConnectWidget(const QString devName); + + void getWirelessDeviceCap(QMap &map); + + void rescan(); + + void keyRingInit(); + void keyRingClear(); + +signals: + //设备插拔 + void deviceStatusChanged(); + //设备名称变化 + void deviceNameChanged(QString oldName, QString newName, int type); + //有线无线列表更新(有线增删、无线增加减少) + void lanAdd(QString devName, QStringList info); + void lanRemove(QString dbusPath); + void lanUpdate(QString devName, QStringList info); + void wlanAdd(QString devName, QStringList info); + void wlanRemove(QString devName,QString ssid); + void wlanactiveConnectionStateChanged(QString devName, QString ssid, QString uuid, int status); + void lanActiveConnectionStateChanged(QString devName, QString uuid, int status); + void activateFailed(QString errorMessage); + void deactivateFailed(QString errorMessage); + //热点断开 + void hotspotDeactivated(QString devName, QString ssid); + void hotspotActivated(QString devName, QString ssid, QString uuid); + //信号强度变化 + void signalStrengthChange(QString devName, QString ssid, int strength); + //安全性变化 + void secuTypeChange(QString devName, QString ssid, QString secuType); + void mainWindowVisibleChanged(const bool &visible); + //列表排序 + void timeToUpdate(); +public slots: + +protected: + void keyPressEvent(QKeyEvent *event); + bool eventFilter(QObject *watched, QEvent *event) override; + void paintEvent(QPaintEvent *event); + +private: + void firstlyStart(); //一级启动 + void secondaryStart(); //二级启动 + bool m_loadFinished = false; //是否二级启动已执行完 + QTimer * m_secondaryStartTimer = nullptr; //执行二级启动的倒计时 + void initPlatform(); + void initWindowProperties(); + void initTransparency(); + void paintWithTrans(); + void initUI(); + void initDbusConnnect(); + void initTrayIcon(); + void resetTrayIconTool(); + void initWindowTheme(); + void resetWindowTheme(); + void showControlCenter(); + double m_transparency=1.0; //透明度 + QGSettings * m_transGsettings; //透明度配置文件 + int currentIconIndex=0; + QList loadIcons; + QTimer *iconTimer = nullptr; + + //主窗口的主要构成控件 + QTabWidget * m_centralWidget = nullptr; + QHBoxLayout * m_tabBarLayout = nullptr; + QLabel * m_lanLabel = nullptr; + QLabel * m_wlanLabel = nullptr; + + LanPage * m_lanWidget = nullptr; + WlanPage * m_wlanWidget = nullptr; + + //监听主题的Gsettings + QGSettings * m_styleGsettings = nullptr; + + //获取和重置窗口位置 + void resetWindowPosition(); + QDBusInterface * m_positionInterface = nullptr; + + //托盘图标,托盘图标右键菜单 + QSystemTrayIcon * m_trayIcon = nullptr; + QMenu * m_trayIconMenu = nullptr; + QAction * m_showMainwindowAction = nullptr; + QAction * m_showSettingsAction = nullptr; + + bool m_lanIsLoading = false; + bool m_wlanIsLoading = false; + + bool m_isShowInCenter = false; + + IconActiveType iconStatus = IconActiveType::NOT_CONNECTED; + + QMap m_createPagePtrMap; + +public slots: + void onShowMainWindow(int type); + +private slots: + void onTransChanged(); + void onTrayIconActivated(QSystemTrayIcon::ActivationReason reason); + void onShowMainwindowActionTriggled(); + void onShowSettingsActionTriggled(); + void onThemeChanged(const QString &key); + void onRefreshTrayIcon(); + void onSetTrayIconLoading(); + void onLanConnectStatusToChangeTrayIcon(int state); + void onWlanConnectStatusToChangeTrayIcon(int state); + void onConnectivityChanged(NetworkManager::Connectivity connectivity); + void onTabletModeChanged(bool mode); +}; + +#endif // MAINWINDOW_H diff --git a/src/frontend/netdetails/coninfo.h b/src/frontend/netdetails/coninfo.h new file mode 100644 index 00000000..abb36082 --- /dev/null +++ b/src/frontend/netdetails/coninfo.h @@ -0,0 +1,269 @@ +#ifndef CONINFO_H +#define CONINFO_H + +#include +#include +#include +#include +#include +#include +#include "kywirelessnetitem.h" +#include "kylinconnectresource.h" +#include "kylinactiveconnectresource.h" +#include "kywirelessconnectoperation.h" +#include "kywirelessnetresource.h" +#include "kyenterpricesettinginfo.h" + +#define AUTO_CONFIG 0 +#define MANUAL_CONFIG 1 + +enum PeapInnerType +{ + MSCHAPV2_PEAP = 0, + MD5_PEAP, + GTC_PEAP, +}; + +enum TtlsInnerType +{ + PAP = 0, + MSCHAP, + MSCHAPV2_EAP, + MSCHAPV2, + CHAP, + MD5_EAP, + GTC_EAP +}; + +class LineEdit : public QLineEdit +{ + Q_OBJECT + +public: + explicit LineEdit(QWidget *parent = nullptr) : QLineEdit(parent) {} + ~LineEdit() {} + +protected: + void contextMenuEvent(QContextMenuEvent *event) { + QMenu *menu = createStandardContextMenu();//默认的标准右键菜单,如果不需要刻意完全自己实现 + menu->setPalette(this->palette()); + menu->exec(event->globalPos()); + delete menu; + } +}; + +class ConInfo { +public: + QString strConName; + QString strConType; + QString strSecType; + KySecuType secType = WPA_AND_WPA2_PERSONAL; + QString strPassword; + QString strChan; + QString strMac; + QString strHz; + QString strBandWidth; + QString strDynamicIpv4; + QString strDynamicIpv6; + QString strDynamicIpv4Dns; + bool isAutoConnect = false; + + KyIpConfigType ipv4ConfigType = CONFIG_IP_DHCP; + QString strIPV4Address; + QString strIPV4NetMask; + QString strIPV4FirDns; + QString strIPV4SecDns; + QString strIPV4GateWay; + + KyIpConfigType ipv6ConfigType = CONFIG_IP_DHCP; + QString strIPV6Address; + int iIPV6Prefix; + QString strIPV6FirDns; + QString strIPV6SecDns; + QString strIPV6GateWay; + + KyEapMethodType enterpriseType; + KyEapMethodTlsInfo tlsInfo; + KyEapMethodPeapInfo peapInfo; + KyEapMethodTtlsInfo ttlsInfo; +}; + +static void setFramePalette(QFrame *widget, QPalette &pal) { + QList lineEditList = widget->findChildren(); + for (int i = 0; i < lineEditList.count(); ++i) { + lineEditList.at(i)->setPalette(pal); + lineEditList.at(i)->setContextMenuPolicy(Qt::DefaultContextMenu); + } + QList comboBoxList = widget->findChildren(); + for (int i = 0; i < comboBoxList.count(); ++i) { + comboBoxList.at(i)->setPalette(pal); + if (comboBoxList.at(i)->view()) { + comboBoxList.at(i)->view()->setPalette(pal); + } + } +} + +static QPalette lightPalette(QWidget *widget) +{ + auto palette = widget->palette(); + //ukui-light palette UKUI3.1 + QColor windowText_at(38, 38, 38), + windowText_iat(38, 38, 38), + windowText_dis(166, 166, 166), + button_at(230, 230, 230), + button_iat(230, 230, 230), + button_dis(233, 233, 233), + light_at(255, 255, 255), + light_iat(255, 255, 255), + light_dis(242, 242, 242), + midlight_at(218, 218, 218), + midlight_iat(218, 218, 218), + midlight_dis(230, 230, 230), + dark_at(77, 77, 77), + dark_iat(77, 77, 77), + dark_dis(64, 64, 64), + mid_at(115, 115, 115), + mid_iat(115, 115, 115), + mid_dis(102, 102, 102), + text_at(38, 38, 38), + text_iat(38, 38, 38), + text_dis(140, 140, 140), + brightText_at(89, 89, 89), + brightText_iat(89, 89, 89), + brightText_dis(77, 77, 77), + buttonText_at(38, 38, 38), + buttonText_iat(38, 38, 38), + buttonText_dis(179, 179, 179), + base_at(255, 255, 255), + base_iat(245, 245, 245), + base_dis(237, 237, 237), + window_at(245, 245, 245), + window_iat(237, 237, 237), + window_dis(230, 230, 230), + shadow_at(0, 0, 0, 16), + shadow_iat(0, 0, 0, 16), + shadow_dis(0, 0, 0, 21), +// shadow_at(214, 214, 214), +// shadow_iat(214, 214, 214), +// shadow_dis(201, 201, 201), + highLight_at(55, 144, 250), + highLight_iat(55, 144, 250), + highLight_dis(233, 233, 233), + highLightText_at(255, 255, 255), + highLightText_iat(255, 255, 255), + highLightText_dis(179, 179, 179), + link_at(55, 144, 250), + link_iat(55, 144, 250), + link_dis(55, 144, 250), + linkVisited_at(114, 46, 209), + linkVisited_iat(114, 46, 209), + linkVisited_dis(114, 46, 209), + alternateBase_at(245, 245, 245), + alternateBase_iat(245, 245, 245), + alternateBase_dis(245, 245, 245), + noRale_at(240, 240, 240), + noRole_iat(240, 240, 240), + noRole_dis(217, 217, 217), + toolTipBase_at(255, 255, 255), + toolTipBase_iat(255, 255, 255), + toolTipBase_dis(255, 255, 255), + toolTipText_at(38, 38, 38), + toolTipText_iat(38, 38, 38), + toolTipText_dis(38, 38, 38), + placeholderText_at(38, 38, 38), + placeholderText_iat(38, 38, 38), + placeholderText_dis(38, 38, 38); + + + + palette.setColor(QPalette::Active, QPalette::WindowText, windowText_at); + palette.setColor(QPalette::Inactive, QPalette::WindowText, windowText_iat); + palette.setColor(QPalette::Disabled, QPalette::WindowText, windowText_dis); + + palette.setColor(QPalette::Active, QPalette::Button, button_at); + palette.setColor(QPalette::Inactive, QPalette::Button, button_iat); + palette.setColor(QPalette::Disabled, QPalette::Button, button_dis); + + palette.setColor(QPalette::Active, QPalette::Light, light_at); + palette.setColor(QPalette::Inactive, QPalette::Light, light_iat); + palette.setColor(QPalette::Disabled, QPalette::Light, light_dis); + + palette.setColor(QPalette::Active, QPalette::Midlight, midlight_at); + palette.setColor(QPalette::Inactive, QPalette::Midlight, midlight_iat); + palette.setColor(QPalette::Disabled, QPalette::Midlight, midlight_dis); + + palette.setColor(QPalette::Active, QPalette::Dark, dark_at); + palette.setColor(QPalette::Inactive, QPalette::Dark, dark_iat); + palette.setColor(QPalette::Disabled, QPalette::Dark, dark_dis); + + palette.setColor(QPalette::Active, QPalette::Mid, mid_at); + palette.setColor(QPalette::Inactive, QPalette::Mid, mid_iat); + palette.setColor(QPalette::Disabled, QPalette::Mid, mid_dis); + + palette.setColor(QPalette::Active, QPalette::Text, text_at); + palette.setColor(QPalette::Inactive, QPalette::Text, text_iat); + palette.setColor(QPalette::Disabled, QPalette::Text, text_dis); + + palette.setColor(QPalette::Active, QPalette::BrightText, brightText_at); + palette.setColor(QPalette::Inactive, QPalette::BrightText, brightText_iat); + palette.setColor(QPalette::Disabled, QPalette::BrightText, brightText_dis); + + palette.setColor(QPalette::Active, QPalette::ButtonText, buttonText_at); + palette.setColor(QPalette::Inactive, QPalette::ButtonText, buttonText_iat); + palette.setColor(QPalette::Disabled, QPalette::ButtonText, buttonText_dis); + + palette.setColor(QPalette::Active, QPalette::Base, base_at); + palette.setColor(QPalette::Inactive, QPalette::Base, base_iat); + palette.setColor(QPalette::Disabled, QPalette::Base, base_dis); + + palette.setColor(QPalette::Active, QPalette::Window, window_at); + palette.setColor(QPalette::Inactive, QPalette::Window, window_iat); + palette.setColor(QPalette::Disabled, QPalette::Window, window_dis); + + palette.setColor(QPalette::Active, QPalette::Shadow, shadow_at); + palette.setColor(QPalette::Inactive, QPalette::Shadow, shadow_iat); + palette.setColor(QPalette::Disabled, QPalette::Shadow, shadow_dis); + + palette.setColor(QPalette::Active, QPalette::Highlight, highLight_at); + palette.setColor(QPalette::Inactive, QPalette::Highlight, highLight_iat); + palette.setColor(QPalette::Disabled, QPalette::Highlight, highLight_dis); + + palette.setColor(QPalette::Active, QPalette::HighlightedText, highLightText_at); + palette.setColor(QPalette::Inactive, QPalette::HighlightedText, highLightText_iat); + palette.setColor(QPalette::Disabled, QPalette::HighlightedText, highLightText_dis); + + palette.setColor(QPalette::Active, QPalette::Link, link_at); + palette.setColor(QPalette::Inactive, QPalette::Link, link_iat); + palette.setColor(QPalette::Disabled, QPalette::Link, link_dis); + + palette.setColor(QPalette::Active, QPalette::LinkVisited, linkVisited_at); + palette.setColor(QPalette::Inactive, QPalette::LinkVisited, linkVisited_iat); + palette.setColor(QPalette::Disabled, QPalette::LinkVisited, linkVisited_dis); + + palette.setColor(QPalette::Active, QPalette::AlternateBase, alternateBase_at); + palette.setColor(QPalette::Inactive, QPalette::AlternateBase, alternateBase_iat); + palette.setColor(QPalette::Disabled, QPalette::AlternateBase, alternateBase_dis); + + palette.setColor(QPalette::Active, QPalette::NoRole, noRale_at); + palette.setColor(QPalette::Inactive, QPalette::NoRole, noRole_iat); + palette.setColor(QPalette::Disabled, QPalette::NoRole, noRole_dis); + + palette.setColor(QPalette::Active, QPalette::ToolTipBase, toolTipBase_at); + palette.setColor(QPalette::Inactive, QPalette::ToolTipBase, toolTipBase_iat); + palette.setColor(QPalette::Disabled, QPalette::ToolTipBase, toolTipBase_dis); + + palette.setColor(QPalette::Active, QPalette::ToolTipText, toolTipText_at); + palette.setColor(QPalette::Inactive, QPalette::ToolTipText, toolTipText_iat); + palette.setColor(QPalette::Disabled, QPalette::ToolTipText, toolTipText_dis); + +#if (QT_VERSION >= QT_VERSION_CHECK(5,12,0)) + palette.setColor(QPalette::Active, QPalette::PlaceholderText, placeholderText_at); + palette.setColor(QPalette::Inactive, QPalette::PlaceholderText, placeholderText_iat); + palette.setColor(QPalette::Disabled, QPalette::PlaceholderText, placeholderText_dis); +#endif + + return palette; + +} + +#endif // CONINFO_H diff --git a/src/frontend/netdetails/creatnetpage.cpp b/src/frontend/netdetails/creatnetpage.cpp new file mode 100644 index 00000000..6034c50a --- /dev/null +++ b/src/frontend/netdetails/creatnetpage.cpp @@ -0,0 +1,227 @@ +#include "creatnetpage.h" +#include "math.h" + +#define MAX_NAME_LENGTH 32 + +CreatNetPage::CreatNetPage(QWidget *parent):QFrame(parent) +{ + initUI(); + initComponent(); +} + +void CreatNetPage::initUI() +{ + connNameEdit = new LineEdit(this); + connNameEdit->setMaxLength(MAX_NAME_LENGTH); + ipv4ConfigCombox = new QComboBox(this); + ipv4addressEdit = new LineEdit(this); + netMaskEdit = new LineEdit(this); + gateWayEdit = new LineEdit(this); + firstDnsEdit = new LineEdit(this); + secondDnsEdit = new LineEdit(this); + + m_connNameLabel = new QLabel(this); + m_configLabel = new QLabel(this); + m_addressLabel = new QLabel(this); + m_maskLabel = new QLabel(this); + m_gateWayLabel = new QLabel(this); + m_dnsLabel = new QLabel(this); + m_secDnsLabel = new QLabel(this); + + m_connNameLabel->setText(tr("Connection Name")); + m_configLabel->setText(tr("Ipv4Config")); + m_addressLabel->setText(tr("Address")); + m_maskLabel->setText(tr("Netmask")); + m_gateWayLabel->setText(tr("Default Gateway")); + m_dnsLabel->setText(tr("Prefs DNS")); + m_secDnsLabel->setText(tr("Alternative DNS")); + + m_detailLayout = new QFormLayout(this); + m_detailLayout->addRow(m_connNameLabel,connNameEdit); + m_detailLayout->addRow(m_configLabel,ipv4ConfigCombox); + m_detailLayout->addRow(m_addressLabel,ipv4addressEdit); + m_detailLayout->addRow(m_maskLabel,netMaskEdit); + m_detailLayout->addRow(m_gateWayLabel,gateWayEdit); + m_detailLayout->addRow(m_dnsLabel,firstDnsEdit); + m_detailLayout->addRow(m_secDnsLabel,secondDnsEdit); + + ipv4ConfigCombox->addItem(tr("Auto(DHCP)"), AUTO_CONFIG); //"自动(DHCP)" + ipv4ConfigCombox->addItem(tr("Manual"), MANUAL_CONFIG); //"手动" + + + // IP的正则格式限制 + QRegExp rx("\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b"); + + ipv4addressEdit->setValidator(new QRegExpValidator(rx, this)); + gateWayEdit->setValidator(new QRegExpValidator(rx, this)); + netMaskEdit->setValidator(new QRegExpValidator(rx, this)); + firstDnsEdit->setValidator(new QRegExpValidator(rx, this)); + secondDnsEdit->setValidator(new QRegExpValidator(rx, this)); +} + +void CreatNetPage::initComponent() { + if (ipv4ConfigCombox->currentIndex() == AUTO_CONFIG) { + setLineEnabled(false); + } else if (ipv4ConfigCombox->currentIndex() == MANUAL_CONFIG) { + setLineEnabled(true); + } + connect(ipv4ConfigCombox, SIGNAL(currentIndexChanged(int)), this, SLOT(configChanged(int))); + + connect(connNameEdit, SIGNAL(textChanged(QString)), this, SLOT(setEnableOfSaveBtn())); + connect(ipv4ConfigCombox, SIGNAL(currentIndexChanged(int)), this, SLOT(setEnableOfSaveBtn())); + connect(netMaskEdit, SIGNAL(textChanged(QString)), this, SLOT(setEnableOfSaveBtn())); + connect(gateWayEdit, SIGNAL(textChanged(QString)), this, SLOT(setEnableOfSaveBtn())); + connect(firstDnsEdit, SIGNAL(textChanged(QString)), this, SLOT(setEnableOfSaveBtn())); + connect(secondDnsEdit, SIGNAL(textChanged(QString)), this, SLOT(setEnableOfSaveBtn())); +} + +bool CreatNetPage::checkConnectBtnIsEnabled() +{ + if (connNameEdit->text().isEmpty()) { + qDebug() << "create connName empty or invalid"; + return false; + } + qDebug() << "checkConnectBtnIsEnabled currentIndex" << ipv4ConfigCombox->currentIndex(); + if (ipv4ConfigCombox->currentIndex() == AUTO_CONFIG) { + return true; + } else { + if (ipv4addressEdit->text().isEmpty() || !getTextEditState(ipv4addressEdit->text())) { + qDebug() << "create ipv4address empty or invalid"; + return false; + } + + if (netMaskEdit->text().isEmpty() || !netMaskIsValide(netMaskEdit->text())) { + qDebug() << "create ipv4 netMask empty or invalid"; + return false; + } + + if (gateWayEdit->text().isEmpty() || !getTextEditState(gateWayEdit->text())) { + qDebug() << "create ipv4 gateway empty or invalid"; + return false; + } + + if (firstDnsEdit->text().isEmpty() && !secondDnsEdit->text().isEmpty()) { + qDebug() << "create ipv4 dns sort invalid"; + return false; + } + + if (!getTextEditState(firstDnsEdit->text())) { + qDebug() << "create ipv4 first dns invalid"; + return false; + } + + if (!getTextEditState(secondDnsEdit->text())) { + qDebug() << "create ipv4 second dns invalid"; + return false; + } + } + return true; +} + +void CreatNetPage::configChanged(int index) { + if (index == AUTO_CONFIG) { + setLineEnabled(false); + } + if (index == MANUAL_CONFIG) { + setLineEnabled(true); + } +} + +void CreatNetPage::setLineEnabled(bool check) { + + ipv4addressEdit->setEnabled(check); + netMaskEdit->setEnabled(check); + gateWayEdit->setEnabled(check); + firstDnsEdit->setEnabled(check); + secondDnsEdit->setEnabled(check); + + if (!check) { + ipv4addressEdit->clear(); + netMaskEdit->clear(); + gateWayEdit->clear(); + firstDnsEdit->clear(); + secondDnsEdit->clear(); + } +} + +void CreatNetPage::setEnableOfSaveBtn() { + emit setCreatePageState(checkConnectBtnIsEnabled()); +} + +bool CreatNetPage::getTextEditState(QString text) +{ + if (text.isEmpty()) { + return true; + } + QRegExp rx("\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b"); + + bool match = false; + match = rx.exactMatch(text); + + return match; +} + +void CreatNetPage::constructIpv4Info(KyConnectSetting &setting) +{ + setting.m_connectName = connNameEdit->text(); + QString ipv4address =ipv4addressEdit->text(); + QString netMask = getNetMaskText(netMaskEdit->text()); + QString gateWay = gateWayEdit->text(); + qDebug() << "constructIpv4Info: " << "ipv4address " << ipv4address + << " netMask " << netMask + << " gateWay " << gateWay; + + QStringList dnsList; + dnsList.empty(); + if (!firstDnsEdit->text().isEmpty()) { + dnsList << firstDnsEdit->text(); + if (!secondDnsEdit->text().isEmpty()) { + dnsList << secondDnsEdit->text(); + } + } + if (ipv4ConfigCombox->currentData() == AUTO_CONFIG) { + setting.setIpConfigType(IPADDRESS_V4, CONFIG_IP_DHCP); + } else { + setting.setIpConfigType(IPADDRESS_V4, CONFIG_IP_MANUAL); + setting.ipv4AddressConstruct(ipv4address, netMask, gateWay, dnsList); + } + +} + +bool CreatNetPage::netMaskIsValide(QString text) +{ + if (getTextEditState(text)) { + return true; + } else { + if (text.length() > 0 && text.length() < 3) { + int num = text.toInt(); + if (num > 0 && num < 33) { + return true; + } + } + } + return false; +} + +QString CreatNetPage::getNetMaskText(QString text) +{ + if (text.length() > 2) { + return text; + } + + int num = text.toInt(); + QStringList list; + list << "0" << "0" << "0" << "0"; + int count = 0; + while (num - 8 >= 0) { + list[count] = "255"; + num = num - 8; + count ++; + } + if (num > 0) { + int size = pow(2, 8) - pow(2,(8-num)); + list[count] = QString::number(size); + } + return QString("%1.%2.%3.%4").arg(list[0],list[1],list[2],list[3]); +} + diff --git a/src/frontend/netdetails/creatnetpage.h b/src/frontend/netdetails/creatnetpage.h new file mode 100644 index 00000000..b0809ba0 --- /dev/null +++ b/src/frontend/netdetails/creatnetpage.h @@ -0,0 +1,62 @@ +#ifndef CREATNETPAGE_H +#define CREATNETPAGE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "coninfo.h" + +class CreatNetPage : public QFrame +{ + Q_OBJECT +public: + CreatNetPage(QWidget *parent = nullptr); + + void constructIpv4Info(KyConnectSetting &setting); +private: + LineEdit *connNameEdit; + QComboBox *ipv4ConfigCombox; + LineEdit *ipv4addressEdit; + LineEdit *netMaskEdit; + LineEdit *gateWayEdit; + LineEdit *firstDnsEdit; + LineEdit *secondDnsEdit; + +private: + QFormLayout *m_detailLayout; + QVBoxLayout *mvBoxLayout; + QLabel *m_connNameLabel; + QLabel *m_configLabel; + QLabel *m_addressLabel; + QLabel *m_maskLabel; + QLabel *m_gateWayLabel; + QLabel *m_dnsLabel; + QLabel *m_secDnsLabel; +private: + void initUI(); + void initComponent(); + void setLineEnabled(bool check); + void configSave(); + bool getTextEditState(QString text); + bool checkConnectBtnIsEnabled(); + + bool netMaskIsValide(QString text); + QString getNetMaskText(QString text); + +private slots: + void setEnableOfSaveBtn(); + void configChanged(int index); +Q_SIGNALS: + void setCreatePageState(bool); + +}; + +#endif // CREATNETPAGE_H diff --git a/src/frontend/netdetails/customtabstyle.cpp b/src/frontend/netdetails/customtabstyle.cpp new file mode 100644 index 00000000..c8683cc8 --- /dev/null +++ b/src/frontend/netdetails/customtabstyle.cpp @@ -0,0 +1,73 @@ +#include "customtabstyle.h" + + +CustomTabStyle::CustomTabStyle() +{ + +} + +QSize CustomTabStyle::sizeFromContents(QStyle::ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const +{ + QSize s = QProxyStyle::sizeFromContents(type, option, size, widget); + if (type == QStyle::CT_TabBarTab) { + s.transpose(); + s.rwidth() = 60; // 设置每个tabBar中item的大小 + s.rheight() = 36; + } + return s; +} + +void CustomTabStyle::drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const +{ + if (element == CE_TabBarTab) { + if (const QStyleOptionTab *tab = qstyleoption_cast(option)) { + QRect allRect = tab->rect; + if (tab->state & QStyle::State_Selected) { //选中状态:tab的Qlabel为矩形,底色为白色,边框淡灰色,文字为淡蓝色且加粗居中(具体颜色值由拾色器提取) + painter->save(); + painter->setPen(0x3790FA); //设置画笔颜色为淡灰色 + painter->setBrush(QBrush(0x3790FA)); //设置画刷为白色 + painter->drawRoundedRect(allRect.adjusted(0,0,0,0),6,6); //重绘tab的矩形边框 + painter->restore(); //还原为默认 + + painter->save(); + painter->setPen(0xffffff); //重新设置画笔颜色为淡蓝色 + QTextOption option; + option.setAlignment(Qt::AlignCenter); //设置文字居中 + painter->drawText(allRect, tab->text, option); //重绘文字 + painter->restore(); + } + else if(tab->state & QStyle::State_MouseOver) { //hover状态:tab的Qlabel为矩形,底色为灰色,边框仍未淡灰色,文字加粗居中 + painter->save(); + painter->setPen(tab->palette.color(QPalette::Window)); //设置画笔颜色为淡灰色 + painter->setBrush(tab->palette.color(QPalette::Window)); //设置画刷为灰色 + painter->drawRoundedRect(allRect.adjusted(0,0,0,0),6,6); //重绘tab的矩形边框 + painter->restore(); //还原 + + painter->save(); + QTextOption option; + option.setAlignment(Qt::AlignCenter); //设置文字居中 + painter->drawText(allRect, tab->text, option); //重绘文字 + painter->restore(); + } + else //其它的:tab的Qlabel为矩形,底色为灰色,边框为淡灰色不变,文字不加粗但居中 + { + painter->save(); + painter->setPen(tab->palette.color(QPalette::Button)); + painter->setBrush(tab->palette.color(QPalette::Button)); + painter->drawRoundedRect(allRect.adjusted(0,0,0,0),6,6); //重绘tab的矩形边框 + painter->restore(); + painter->save(); + QTextOption option; + option.setAlignment(Qt::AlignCenter); + painter->drawText(allRect, tab->text, option); + painter->restore(); + } + return; + } + } + + if (element == CE_TabBarTab) { + QProxyStyle::drawControl(element, option, painter, widget); + } +} + diff --git a/src/frontend/netdetails/customtabstyle.h b/src/frontend/netdetails/customtabstyle.h new file mode 100644 index 00000000..75a09825 --- /dev/null +++ b/src/frontend/netdetails/customtabstyle.h @@ -0,0 +1,19 @@ +#ifndef CUSTOMTABSTYLE_H +#define CUSTOMTABSTYLE_H + +#include +#include +#include +#include +#include +class CustomTabStyle : public QProxyStyle +{ +public: + CustomTabStyle(); + QSize sizeFromContents(ContentsType type, const QStyleOption *option, + const QSize &size, const QWidget *widget) const; + + void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const; +}; + +#endif // CUSTOMTABSTYLE_H diff --git a/src/frontend/netdetails/detailpage.cpp b/src/frontend/netdetails/detailpage.cpp new file mode 100644 index 00000000..381b913a --- /dev/null +++ b/src/frontend/netdetails/detailpage.cpp @@ -0,0 +1,346 @@ +#include "detailpage.h" +#include +#include + +#define MAX_NAME_LENGTH 32 +#define MAX_LABEL_WIDTH 250 +extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); + +DetailPage::DetailPage(bool isWlan, bool isCreate, QWidget *parent) + : m_IsWlan(isWlan), m_IsCreate(isCreate), QFrame(parent) +{ + this->setFrameShape(QFrame::Shape::StyledPanel); + this->setMaximumWidth(960); + initUI(); + if (isCreate) { + connect(m_SSIDEdit, &LineEdit::textEdited, this, &DetailPage::setEnableOfSaveBtn); + } +} + +DetailPage::~DetailPage() +{ + if (m_copiedTip != nullptr) { + delete m_copiedTip; + m_copiedTip = nullptr; + } +} + +void DetailPage::setSSID(const QString &ssid) { + if (m_IsCreate) { + return; + } + m_formerSSID = ssid; + QFontMetrics fontMetrics(this->font()); + int fontSize = fontMetrics.width(ssid); + if (fontSize > this->width()) { + this->m_SSIDLabel->setText(fontMetrics.elidedText(ssid, Qt::ElideRight, this->width())); + this->setToolTip(ssid); + } else { + this->m_SSIDLabel->setText(ssid); + this->setToolTip(""); + } +} + +void DetailPage::setProtocol(const QString &protocol) { + this->m_Protocol->setText(protocol); +} + +void DetailPage::setSecType(const QString &secType) { + this->m_SecType->setText(secType); +} + +void DetailPage::setHz(const QString &hz) { + this->m_Hz->setText(hz); +} + +void DetailPage::setChan(const QString &chan) { + this->m_Chan->setText(chan); +} + +void DetailPage::setBandWidth(const QString &brandWidth) { + this->m_BandWidth->setText(brandWidth); +} + +void DetailPage::setIpv4(const QString &ipv4) { + this->m_IPV4->setText(ipv4); +} + +void DetailPage::setIpv4Dns(const QString &ipv4Dns) { + this->m_IPV4Dns->setText(ipv4Dns); +} + +void DetailPage::setIpv6(const QString &ipv6) { + m_formerIPV6 = ipv6; + this->m_IPV6->setText(ipv6); +} + +void DetailPage::setMac(const QString &mac) { + this->m_Mac->setText(mac); +} + +void DetailPage::setAutoConnect(bool flag) +{ + if (!m_IsWlan) { + return; + } + this->m_forgetNetBox->setChecked(flag); +} + +void DetailPage::getSsid(QString &ssid) +{ + if (m_IsCreate) { + ssid = m_SSIDEdit->text(); + } else { + ssid = m_SSIDLabel->text(); + } +} + +bool DetailPage::checkIsChanged(const ConInfo info) +{ + if (!m_IsWlan) { + return false; + } + if (info.isAutoConnect != m_forgetNetBox->isChecked()) { + return true; + } else { + return false; + } +} + +void DetailPage::addDetailItem(QListWidget *listWidget, QWidget *detailWidget) +{ + QListWidgetItem *listWidgetItem = new QListWidgetItem(listWidget); + listWidgetItem->setSizeHint(QSize(listWidget->width(),36)); + listWidgetItem->setFlags(Qt::NoItemFlags); + listWidget->addItem(listWidgetItem); + listWidget->setItemWidget(listWidgetItem, detailWidget); +} + +void DetailPage::newCopiedTip() +{ + //设置“复制成功”消息弹窗格式 + m_copiedTip = new KBallonTip(); + m_copiedTip->setTipType(Normal); + m_copiedTip->setFixedSize(158, 58); + m_copiedTip->setWindowFlags(Qt::FramelessWindowHint); + m_copiedTip->setAttribute(Qt::WA_TranslucentBackground, true); + m_copiedTip->setText(tr("Copied successfully!")); +} + +QPalette DetailPage::getTheme() +{ + //获取当前主题的颜色 + QPalette pal = qApp->palette(); + QGSettings * styleGsettings = nullptr; + const QByteArray style_id(THEME_SCHAME); + if (QGSettings::isSchemaInstalled(style_id)) { + styleGsettings = new QGSettings(style_id); + QString currentTheme = styleGsettings->get(COLOR_THEME).toString(); + if(currentTheme == "ukui-default"){ + pal = lightPalette(this); + } + } + if (styleGsettings != nullptr) { + delete styleGsettings; + styleGsettings = nullptr; + } + return pal; +} + +void DetailPage::initUI() { + m_layout = new QVBoxLayout(this); + m_layout->setContentsMargins(0,0,0,0); + + QWidget *mDetailFrame = new QFrame(this); + m_DetailLayout = new QVBoxLayout(mDetailFrame); + m_DetailLayout->setContentsMargins(0,0,0,0); + + m_listWidget = new QListWidget(mDetailFrame); + m_listWidget->setFrameShape(QFrame::Shape::NoFrame); + m_listWidget->setBackgroundRole(QPalette::Base); + m_listWidget->setFocusPolicy(Qt::FocusPolicy::NoFocus); + m_DetailLayout->addWidget(m_listWidget); + + if (!m_IsCreate) { + m_SSIDLabel = new QLabel(this); + m_SSIDLabel->adjustSize(); + m_SSIDLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + + m_netCopyButton = new QPushButton(this); + m_netCopyButton->setIcon(QIcon::fromTheme("edit-copy-symbolic")); + m_netCopyButton->setToolTip(tr("Copy all")); + //设置按钮背景颜色-透明 + QPalette btnPal = m_netCopyButton->palette(); + QColor color = qApp->palette().color(QPalette::Background); + color.setAlphaF(0); + btnPal.setColor(QPalette::Button, color); + m_netCopyButton->setPalette(btnPal); + + m_ssidWidget = new DetailWidget(qobject_cast(m_SSIDLabel), m_listWidget, m_netCopyButton); + connect(m_netCopyButton, &QPushButton::clicked, this, &DetailPage::on_btnCopyNetDetail_clicked); + newCopiedTip(); + +// mSSID->setStyleSheet("background:transparent;border-width:0px;border-style:none"); +// mSSID->setFocusPolicy(Qt::NoFocus); + } else { +// mSSID->setStyleSheet("border-width:1px;;border-style:solid;border-color:black;border-radius:2px"); + m_SSIDEdit = new LineEdit(this); + m_SSIDEdit->setMaximumWidth(MAX_LABEL_WIDTH); + m_SSIDEdit->setAlignment(Qt::AlignRight); + m_SSIDEdit->setStyleSheet("border-top:0px solid;border-bottom:1px solid;border-left:0px solid;border-right: 0px solid;background:transparent"); + m_SSIDEdit->setPlaceholderText(tr("Please input SSID:")); + m_SSIDEdit->setMaxLength(MAX_NAME_LENGTH); + m_ssidWidget = new DetailWidget(qobject_cast(m_SSIDEdit), m_listWidget); + } + + + m_ssidWidget->setKey(tr("SSID:")); + + m_Protocol = new QLabel(this); + m_protocolWidget = new DetailWidget(qobject_cast(m_Protocol), m_listWidget); + m_protocolWidget->setKey(tr("Protocol:")); + + m_SecType = new QLabel(this); + m_secTypeWidget = new DetailWidget(qobject_cast(m_SecType)); + m_secTypeWidget->setKey(tr("Security Type:")); + + m_Hz = new QLabel(this); + m_hzWidget = new DetailWidget(qobject_cast(m_Hz)); + m_hzWidget->setKey(tr("Hz:")); + + m_Chan = new QLabel(this); + m_chanelWidget = new DetailWidget(qobject_cast(m_Chan)); + m_chanelWidget->setKey(tr("Chan:")); + + m_BandWidth = new QLabel(this); + m_bandwidthWidget = new DetailWidget(qobject_cast(m_BandWidth), m_listWidget); + m_bandwidthWidget->setKey(tr("BandWidth:")); + + m_IPV4 = new QLabel(this); + m_ipv4Widget = new DetailWidget(qobject_cast(m_IPV4), m_listWidget); + m_ipv4Widget->setKey(tr("IPV4:")); + + m_IPV4Dns = new QLabel(this); + m_ipv4DnsWidget = new DetailWidget(qobject_cast(m_IPV4Dns), m_listWidget); + m_ipv4DnsWidget->setKey(tr("IPV4 Dns:")); + + m_IPV6 = new FixLabel(this); + m_IPV6->setFixedWidth(MAX_LABEL_WIDTH); + m_IPV6->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + m_ipv6Widget = new DetailWidget(qobject_cast(m_IPV6), m_listWidget); + m_ipv6Widget->setKey(tr("IPV6:")); + + m_Mac = new QLabel(this); + m_macWidget = new DetailWidget(qobject_cast(m_Mac), m_listWidget); + m_macWidget->setKey(tr("Mac:")); + + if (m_IsWlan) { + m_autoConnect = new QLabel(this); + m_forgetNetBox = new QCheckBox(this); + + m_autoConnect->setText(tr("Auto Connection")); + m_AutoLayout = new QHBoxLayout(this); + QSpacerItem *horizontalSpacer; + horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + + m_AutoLayout->addSpacing(20); + m_AutoLayout->addWidget(m_forgetNetBox); + m_AutoLayout->addWidget(m_autoConnect); + m_AutoLayout->addSpacerItem(horizontalSpacer); + } + + this->addDetailItem(m_listWidget, m_ssidWidget); + this->addDetailItem(m_listWidget, m_protocolWidget); + if (m_IsWlan) { + this->addDetailItem(m_listWidget, m_secTypeWidget); + this->addDetailItem(m_listWidget, m_hzWidget); + this->addDetailItem(m_listWidget, m_chanelWidget); + } + this->addDetailItem(m_listWidget, m_bandwidthWidget); + this->addDetailItem(m_listWidget, m_ipv6Widget); + this->addDetailItem(m_listWidget, m_ipv4Widget); + this->addDetailItem(m_listWidget, m_ipv4DnsWidget); + this->addDetailItem(m_listWidget, m_macWidget); + + QPalette mpal(m_listWidget->palette()); + mpal.setColor(QPalette::Base, qApp->palette().base().color()); + mpal.setColor(QPalette::AlternateBase, qApp->palette().alternateBase().color()); + m_listWidget->setAlternatingRowColors(true); +// m_listWidget->setAutoFillBackground(true); + m_listWidget->setPalette(mpal); + + m_layout->addWidget(mDetailFrame); + if (m_IsWlan) { + m_layout->addLayout(m_AutoLayout); + } +} + +void DetailPage::setEnableOfSaveBtn() { + bool saveEnable = true; + if (m_IsCreate) { + saveEnable = !m_SSIDEdit->text().isEmpty(); + } + emit setDetailPageState(saveEnable); +} + +//获取列表信息 +void DetailPage::on_btnCopyNetDetail_clicked() +{ + QStringList netDetailList; + QString ssidCopy = tr("SSID:"); + QString protocolCopy = tr("Protocol:"); + QString securityCopy = tr("Security Type:"); + QString hzCopy= tr ("Hz:"); + QString chanCopy= tr ("Chan:"); + QString bandwithCopy = tr("BandWidth:"); + QString ipv4Copy = tr("IPV4:"); + QString ipv4dnsCopy = tr("IPV4 Dns:"); + QString ipv6Copy = tr("IPV6:"); + QString macCopy = tr("Mac:"); + QString netDetailCopyText; + + ssidCopy.append(m_formerSSID); + protocolCopy.append(this->m_Protocol->text()); + netDetailList.append(ssidCopy); + netDetailList.append(protocolCopy); + + if(m_IsWlan) + { + securityCopy.append(this->m_SecType->text()); + hzCopy.append(this->m_Hz->text()); + chanCopy.append(this->m_Chan->text()); + netDetailList.append(securityCopy); + netDetailList.append(hzCopy); + netDetailList.append(chanCopy); + } + + bandwithCopy += this->m_BandWidth->text(); + ipv6Copy += m_formerIPV6; + ipv4Copy += this->m_IPV4->text(); + ipv4dnsCopy += this->m_IPV4Dns->text(); + macCopy += this->m_Mac->text(); + netDetailList.append(bandwithCopy); + netDetailList.append(ipv4Copy); + netDetailList.append(ipv4dnsCopy); + netDetailList.append(ipv6Copy); + netDetailList.append(macCopy); +// qDebug() << netDetailList; + + //设置剪贴板内容 + netDetailCopyText = netDetailList.join("\n"); + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setText(netDetailCopyText); + + //设置“复制成功”弹窗位置并显示 + if (m_copiedTip != nullptr) { + delete m_copiedTip; + newCopiedTip(); + } + QPoint position = m_ssidWidget->mapToGlobal(this->pos()); + double x = 0.5 * (m_ssidWidget->width() - m_copiedTip->width()); + m_copiedTip->move(position.x() + x, position.y() + 150); + QPalette pal = getTheme(); + m_copiedTip->setPalette(pal); + m_copiedTip->showInfo(); +} + diff --git a/src/frontend/netdetails/detailpage.h b/src/frontend/netdetails/detailpage.h new file mode 100644 index 00000000..c7062629 --- /dev/null +++ b/src/frontend/netdetails/detailpage.h @@ -0,0 +1,102 @@ +#ifndef DETAILPAGE_H +#define DETAILPAGE_H +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "detailwidget.h" +#include "coninfo.h" +#include "kwidget.h" +#include "ktabbar.h" +#include "kballontip.h" +#define THEME_SCHAME "org.ukui.style" +#define COLOR_THEME "styleName" + +using namespace kdk; + +class DetailPage : public QFrame +{ + Q_OBJECT +public: + DetailPage(bool isWlan, bool isCreate = false, QWidget *parent = nullptr); + ~DetailPage(); + void setSSID(const QString &ssid); + void setProtocol(const QString &protocol); + void setSecType(const QString &secType); + void setHz(const QString &hz); + void setChan(const QString &chan); + void setBandWidth(const QString &brandWidth); + void setIpv4(const QString &ipv4); + void setIpv4Dns(const QString &ipv4Dns); + void setIpv6(const QString &ipv6); + void setMac(const QString &mac); + void setAutoConnect(bool flag); + + bool checkIsChanged(const ConInfo info); + + void getSsid(QString &ssid); + +private: + void initUI(); + void addDetailItem(QListWidget *listWidget, QWidget *detailWidget); + void newCopiedTip(); + QPalette getTheme(); + +public: + QListWidget *m_listWidget = nullptr; + DetailWidget *m_ssidWidget = nullptr; + DetailWidget *m_protocolWidget = nullptr; + DetailWidget *m_secTypeWidget = nullptr; + DetailWidget *m_hzWidget = nullptr; + DetailWidget *m_chanelWidget = nullptr; + DetailWidget *m_bandwidthWidget = nullptr; + DetailWidget *m_ipv4Widget = nullptr; + DetailWidget *m_ipv4DnsWidget = nullptr; + DetailWidget *m_ipv6Widget = nullptr; + DetailWidget *m_macWidget = nullptr; + + QPushButton *m_netCopyButton; + LineEdit *m_SSIDEdit; + QLabel *m_SSIDLabel; + QLabel *m_Protocol; + QLabel *m_SecType; + QLabel *m_Hz; + QLabel *m_Chan; + QLabel *m_BandWidth; + QLabel *m_IPV4; + QLabel *m_IPV4Dns; + FixLabel *m_IPV6; + QLabel *m_Mac; + QLabel *m_autoConnect; + KBallonTip *m_copiedTip = nullptr; + +// QWidget *autoFrame; +private: + QVBoxLayout *m_layout; + QVBoxLayout *m_DetailLayout; + QHBoxLayout *m_AutoLayout; + QCheckBox *m_forgetNetBox; + bool m_IsWlan; + bool m_IsCreate; + + QString m_formerSSID; + QString m_formerIPV6; + +private slots: + void setEnableOfSaveBtn(); + void on_btnCopyNetDetail_clicked(); + +signals: + void setDetailPageState(bool); + +}; + +#endif // DETAILPAGE_H diff --git a/src/frontend/netdetails/detailwidget.cpp b/src/frontend/netdetails/detailwidget.cpp new file mode 100644 index 00000000..0b4f4584 --- /dev/null +++ b/src/frontend/netdetails/detailwidget.cpp @@ -0,0 +1,82 @@ +#include "detailwidget.h" +#include +#include + +#define ITEM_HEIGHT 36 +#define ITEM_MARGINS 18,0,16,0 + +#define MAX_LABEL_WIDTH 138 + +FixLabel::FixLabel(QWidget *parent): + QLabel(parent) +{ + +} + +FixLabel::~FixLabel() +{ + +} + +void FixLabel::paintEvent(QPaintEvent *event) +{ + QFontMetrics fontMetrics(this->font()); + int fontSize = fontMetrics.width(mStr); + if (fontSize > this->width()) { + this->setText(fontMetrics.elidedText(mStr, Qt::ElideRight, this->width()), false); + this->setToolTip(mStr); + } else { + this->setText(mStr, false); + this->setToolTip(""); + } + QLabel::paintEvent(event); +} + +void FixLabel::setText(const QString & text, bool saveTextFlag) +{ + if (saveTextFlag) { + mStr = text; + } + QLabel::setText(text); +} + +DetailWidget::DetailWidget(QWidget *valueWidget, QWidget *parent, QWidget *buttonWidget) + : m_valueWidget(valueWidget) , QWidget(parent) , m_copyButton(buttonWidget) +{ +// m_valueWidget = valueWidget; + initUI(); +} + +DetailWidget::~DetailWidget() +{ + +} + +void DetailWidget::initUI() +{ + this->setFixedHeight(ITEM_HEIGHT); + m_mainLayout = new QHBoxLayout(this); + m_mainLayout->setContentsMargins(ITEM_MARGINS); + + m_keyLabel = new FixLabel(this); + m_keyLabel->setMaximumWidth(MAX_LABEL_WIDTH); + m_keyLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); + + m_mainLayout->addWidget(m_keyLabel); + m_mainLayout->addStretch(); + if (m_copyButton != nullptr) { + m_copyButton->setMaximumWidth(ITEM_HEIGHT-8); + m_copyButton->setMaximumHeight(ITEM_HEIGHT-8); + m_mainLayout->addWidget(m_copyButton); + } + m_mainLayout->addWidget(m_valueWidget); + m_valueWidget->setMaximumWidth(100000000000); +} + +void DetailWidget::setKey(const QString &keyLabel) +{ + m_keyLabel->setText(keyLabel); +} + + + diff --git a/src/frontend/netdetails/detailwidget.h b/src/frontend/netdetails/detailwidget.h new file mode 100644 index 00000000..c97ac877 --- /dev/null +++ b/src/frontend/netdetails/detailwidget.h @@ -0,0 +1,45 @@ +#ifndef DetailWidget_H +#define DetailWidget_H + +#include +#include +#include + +//文本长自动省略并添加悬浮 +class FixLabel : public QLabel +{ + + Q_OBJECT +public: + FixLabel(QWidget *parent = nullptr); + ~FixLabel(); + void setText(const QString &text, bool saveTextFlag = true); +private: + void paintEvent(QPaintEvent *event); + +private: + QString mStr; +}; + +class DetailWidget : public QWidget +{ + Q_OBJECT +public: + explicit DetailWidget(QWidget *valueWidget = nullptr, QWidget *parent = nullptr, QWidget *buttonWidget = nullptr); + ~DetailWidget(); + + void setKey(const QString &keyLabel); + +private: + QHBoxLayout *m_mainLayout = nullptr; + FixLabel *m_keyLabel = nullptr; + QWidget *m_valueWidget = nullptr; + QWidget *m_copyButton; + + void initUI(); + +signals: + +}; + +#endif // DetailWidget_H diff --git a/src/frontend/netdetails/ipv4page.cpp b/src/frontend/netdetails/ipv4page.cpp new file mode 100644 index 00000000..7cc11f58 --- /dev/null +++ b/src/frontend/netdetails/ipv4page.cpp @@ -0,0 +1,280 @@ +#include "ipv4page.h" +#include "netdetail.h" +#include "math.h" + +Ipv4Page::Ipv4Page(QWidget *parent):QFrame(parent) +{ + initUI(); + initComponent(); +} + +void Ipv4Page::initUI() { + ipv4ConfigCombox = new QComboBox(this); + ipv4addressEdit = new LineEdit(this); + netMaskEdit = new LineEdit(this); + gateWayEdit = new LineEdit(this); + firstDnsEdit = new LineEdit(this); + secondDnsEdit = new LineEdit(this); + + m_configLabel = new QLabel(this); + m_addressLabel = new QLabel(this); + m_maskLabel = new QLabel(this); + m_gateWayLabel = new QLabel(this); + m_dnsLabel = new QLabel(this); + m_secDnsLabel = new QLabel(this); + + m_configLabel->setText(tr("Ipv4Config")); + m_addressLabel->setText(tr("Address")); + m_maskLabel->setText(tr("Netmask")); + m_gateWayLabel->setText(tr("Default Gateway")); + m_dnsLabel->setText(tr("Prefs DNS")); + m_secDnsLabel->setText(tr("Alternative DNS")); + + m_detailLayout = new QFormLayout(this); + m_detailLayout->addRow(m_configLabel,ipv4ConfigCombox); + m_detailLayout->addRow(m_addressLabel,ipv4addressEdit); + m_detailLayout->addRow(m_maskLabel,netMaskEdit); + m_detailLayout->addRow(m_gateWayLabel,gateWayEdit); + m_detailLayout->addRow(m_dnsLabel,firstDnsEdit); + m_detailLayout->addRow(m_secDnsLabel,secondDnsEdit); + + ipv4ConfigCombox->addItem(tr("Auto(DHCP)")); //"自动(DHCP)" + ipv4ConfigCombox->addItem(tr("Manual")); //"手动" + +// netMaskCombox->addItem(""); +// netMaskCombox->addItem("255.255.255.0"); //24 +// netMaskCombox->addItem("255.255.254.0"); //23 +// netMaskCombox->addItem("255.255.252.0"); //22 +// netMaskCombox->addItem("255.255.0.0"); //16 +// netMaskCombox->addItem("255.0.0.0"); //8 + + + // IP的正则格式限制 + QRegExp rx("\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b"); + + ipv4addressEdit->setValidator(new QRegExpValidator(rx, this)); + gateWayEdit->setValidator(new QRegExpValidator(rx, this)); + netMaskEdit->setValidator(new QRegExpValidator(rx, this)); + firstDnsEdit->setValidator(new QRegExpValidator(rx, this)); + secondDnsEdit->setValidator(new QRegExpValidator(rx, this)); +} + +void Ipv4Page::initComponent() { + if (ipv4ConfigCombox->currentIndex() == AUTO_CONFIG) { + setLineEnabled(false); + } else if (ipv4ConfigCombox->currentIndex() == MANUAL_CONFIG) { + setLineEnabled(true); + } + connect(ipv4ConfigCombox, SIGNAL(currentIndexChanged(int)), this, SLOT(configChanged(int))); + + connect(ipv4ConfigCombox, SIGNAL(currentIndexChanged(int)), this, SLOT(setEnableOfSaveBtn())); + connect(ipv4addressEdit, SIGNAL(textChanged(QString)), this, SLOT(setEnableOfSaveBtn())); + connect(netMaskEdit, SIGNAL(textChanged(QString)), this, SLOT(setEnableOfSaveBtn())); + connect(gateWayEdit, SIGNAL(textChanged(QString)), this, SLOT(setEnableOfSaveBtn())); + connect(firstDnsEdit, SIGNAL(textChanged(QString)), this, SLOT(setEnableOfSaveBtn())); + connect(secondDnsEdit, SIGNAL(textChanged(QString)), this, SLOT(setEnableOfSaveBtn())); +} + +void Ipv4Page::setIpv4Config(KyIpConfigType ipv4Config) +{ + if (ipv4Config == CONFIG_IP_MANUAL) { + ipv4ConfigCombox->setCurrentIndex(MANUAL_CONFIG); + } else { + ipv4ConfigCombox->setCurrentIndex(AUTO_CONFIG); + } +} + +void Ipv4Page::setIpv4(const QString &ipv4) +{ + ipv4addressEdit->setText(ipv4); +} + +void Ipv4Page::setNetMask(const QString &netMask) +{ + netMaskEdit->setText(netMask); +} + +void Ipv4Page::setIpv4FirDns(const QString &ipv4FirDns) +{ + firstDnsEdit->setText(ipv4FirDns); +} + +void Ipv4Page::setIpv4SecDns(const QString &ipv4SecDns) +{ + secondDnsEdit->setText(ipv4SecDns); +} + +void Ipv4Page::setGateWay(const QString &gateWay) +{ + gateWayEdit->setText(gateWay); +} + +bool Ipv4Page::checkIsChanged(const ConInfo info, KyConnectSetting &setting) +{ + bool isChanged = false; + if (ipv4ConfigCombox->currentIndex() == AUTO_CONFIG) { + if (info.ipv4ConfigType != CONFIG_IP_DHCP) { + qDebug() << "ipv4ConfigType change to Auto"; + setting.setIpConfigType(IPADDRESS_V4, CONFIG_IP_DHCP); + QString ipv4address(""); + QString netMask(""); + QString gateWay(""); + QStringList dnsList; + dnsList.empty(); + qDebug() << ipv4address << netMask << gateWay; + setting.ipv4AddressConstruct(ipv4address, netMask, gateWay, dnsList); + isChanged = true; + } + } else { + if (info.ipv4ConfigType != CONFIG_IP_MANUAL) { + qDebug() << "ipv4ConfigType change to Manual"; + setting.setIpConfigType(IPADDRESS_V4, CONFIG_IP_MANUAL); + isChanged = true; + } + qDebug() << "ipv4 netmask " << getNetMaskText(netMaskEdit->text()); + if(info.strIPV4Address != ipv4addressEdit->text() + || info.strIPV4NetMask != /*netMaskEdit->text()*/getNetMaskText(netMaskEdit->text()) + || info.strIPV4GateWay != gateWayEdit->text() + || info.strIPV4FirDns != firstDnsEdit->text() + || info.strIPV4SecDns != secondDnsEdit->text()) { + + qDebug() << "ipv4 info changed"; + QStringList dnsList; + dnsList.empty(); + if (!firstDnsEdit->text().isEmpty()) { + dnsList << firstDnsEdit->text(); + if (!secondDnsEdit->text().isEmpty()) { + dnsList << secondDnsEdit->text(); + } + } + + QString ipv4address =ipv4addressEdit->text(); + QString netMask = getNetMaskText(netMaskEdit->text()); + QString gateWay = gateWayEdit->text(); + qDebug() << ipv4address << netMask << gateWay; + setting.ipv4AddressConstruct(ipv4address, netMask, gateWay, dnsList); + setting.dumpInfo(); + isChanged = true; + } + } + return isChanged; +} + +bool Ipv4Page::checkConnectBtnIsEnabled() +{ + qDebug() << "checkConnectBtnIsEnabled currentIndex" << ipv4ConfigCombox->currentIndex(); + if (ipv4ConfigCombox->currentIndex() == AUTO_CONFIG) { + return true; + } else { + if (ipv4addressEdit->text().isEmpty() || !getTextEditState(ipv4addressEdit->text())) { + qDebug() << "ipv4address empty or invalid"; + return false; + } + + if (netMaskEdit->text().isEmpty() || !netMaskIsValide(netMaskEdit->text())) { + qDebug() << "ipv4 netMask empty or invalid"; + return false; + } + +// if (gateWayEdit->text().isEmpty() || !getTextEditState(gateWayEdit->text())) { +// qDebug() << "ipv4 gateway empty or invalid"; +// return false; +// } + + if (firstDnsEdit->text().isEmpty() && !secondDnsEdit->text().isEmpty()) { + qDebug() << "ipv4 dns sort invalid"; + return false; + } + + if (!getTextEditState(firstDnsEdit->text())) { + qDebug() << "ipv4 first dns invalid"; + return false; + } + + if (!getTextEditState(secondDnsEdit->text())) { + qDebug() << "ipv4 second dns invalid"; + return false; + } + } + return true; +} + +void Ipv4Page::configChanged(int index) { + if (index == AUTO_CONFIG) { + setLineEnabled(false); + } + if (index == MANUAL_CONFIG) { + setLineEnabled(true); + } +} + +void Ipv4Page::setLineEnabled(bool check) { + + ipv4addressEdit->setEnabled(check); + netMaskEdit->setEnabled(check); + gateWayEdit->setEnabled(check); + firstDnsEdit->setEnabled(check); + secondDnsEdit->setEnabled(check); + + if (!check) { + ipv4addressEdit->clear(); + netMaskEdit->clear(); + gateWayEdit->clear(); + firstDnsEdit->clear(); + secondDnsEdit->clear(); + } +} + +void Ipv4Page::setEnableOfSaveBtn() { + emit setIpv4PageState(checkConnectBtnIsEnabled()); +} + +bool Ipv4Page::getTextEditState(QString text) +{ + if (text.isEmpty()) { + return true; + } + QRegExp rx("\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b"); + + bool match = false; + match = rx.exactMatch(text); + + return match; +} + +bool Ipv4Page::netMaskIsValide(QString text) +{ + if (getTextEditState(text)) { + return true; + } else { + if (text.length() > 0 && text.length() < 3) { + int num = text.toInt(); + if (num > 0 && num < 33) { + return true; + } + } + } + return false; +} + +QString Ipv4Page::getNetMaskText(QString text) +{ + if (text.length() > 2) { + return text; + } + + int num = text.toInt(); + QStringList list; + list << "0" << "0" << "0" << "0"; + int count = 0; + while (num - 8 >= 0) { + list[count] = "255"; + num = num - 8; + count ++; + } + if (num > 0) { + int size = pow(2, 8) - pow(2,(8-num)); + list[count] = QString::number(size); + } + return QString("%1.%2.%3.%4").arg(list[0],list[1],list[2],list[3]); +} diff --git a/src/frontend/netdetails/ipv4page.h b/src/frontend/netdetails/ipv4page.h new file mode 100644 index 00000000..25ef07aa --- /dev/null +++ b/src/frontend/netdetails/ipv4page.h @@ -0,0 +1,67 @@ +#ifndef IPV4PAGE_H +#define IPV4PAGE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#include "kylinconnectsetting.h" +#include "coninfo.h" + +class Ipv4Page : public QFrame +{ + Q_OBJECT +public: + Ipv4Page(QWidget *parent = nullptr); + void setIpv4Config(KyIpConfigType ipv4Config); + void setIpv4(const QString &ipv4); + void setNetMask(const QString &netMask); + void setIpv4FirDns(const QString &ipv4FirDns); + void setIpv4SecDns(const QString &ipv4SecDns); + void setGateWay(const QString &gateWay); + + bool checkIsChanged(const ConInfo info, KyConnectSetting &setting); +private: + QComboBox *ipv4ConfigCombox; + LineEdit *ipv4addressEdit; + LineEdit *netMaskEdit; + LineEdit *gateWayEdit; + LineEdit *firstDnsEdit; + LineEdit *secondDnsEdit; + +private: + QFormLayout *m_detailLayout; + QVBoxLayout *mvBoxLayout; + QLabel *m_configLabel; + QLabel *m_addressLabel; + QLabel *m_maskLabel; + QLabel *m_gateWayLabel; + QLabel *m_dnsLabel; + QLabel *m_secDnsLabel; +private: + void initUI(); + void initComponent(); + void setLineEnabled(bool check); + void configSave(); + bool getTextEditState(QString text); + bool netMaskIsValide(QString text); + QString getNetMaskText(QString text); + bool checkConnectBtnIsEnabled(); + + +private slots: + void setEnableOfSaveBtn(); + void configChanged(int index); +Q_SIGNALS: + void setIpv4PageState(bool); + +}; + +#endif // IPV4PAGE_H diff --git a/src/frontend/netdetails/ipv6page.cpp b/src/frontend/netdetails/ipv6page.cpp new file mode 100644 index 00000000..d7453bec --- /dev/null +++ b/src/frontend/netdetails/ipv6page.cpp @@ -0,0 +1,257 @@ +#include "ipv6page.h" +#include "netdetail.h" + +Ipv6Page::Ipv6Page(QWidget *parent):QFrame(parent) +{ + initUI(); + initComponent(); +} + +void Ipv6Page::setIpv6Config(KyIpConfigType ipv6Config) +{ + if (ipv6Config == CONFIG_IP_MANUAL) { + ipv6ConfigCombox->setCurrentIndex(MANUAL_CONFIG); + } else { + ipv6ConfigCombox->setCurrentIndex(AUTO_CONFIG); + } +} + +void Ipv6Page::setIpv6(const QString &ipv6) +{ + ipv6AddressEdit->setText(ipv6); +} + +void Ipv6Page::setIpv6Perfix(const int &ipv6Perfix) +{ + lengthEdit->setText(QString::number(ipv6Perfix)); +} + +void Ipv6Page::setIpv6FirDns(const QString &ipv6FirDns) +{ + firstDnsEdit->setText(ipv6FirDns); +} + +void Ipv6Page::setIpv6SecDns(const QString &ipv6SecDns) +{ + secondDnsEdit->setText(ipv6SecDns); +} + +void Ipv6Page::setGateWay(const QString &gateWay) +{ + gateWayEdit->setText(gateWay); +} + +bool Ipv6Page::checkIsChanged(const ConInfo info, KyConnectSetting &setting) +{ + bool isChanged = false; + if (ipv6ConfigCombox->currentIndex() == AUTO_CONFIG) { + if (info.ipv6ConfigType != CONFIG_IP_DHCP) { + qDebug() << "ipv6ConfigType change to Auto"; + setting.setIpConfigType(IPADDRESS_V6, CONFIG_IP_DHCP); + QString ipv6address(""); + QString prefix(""); + QString gateWay(""); + QStringList dnsList; + dnsList.empty(); + setting.ipv6AddressConstruct(ipv6address, prefix, gateWay, dnsList); + isChanged = true; + } + } else { + if (info.ipv6ConfigType != CONFIG_IP_MANUAL) { + qDebug() << "ipv6ConfigType change to Manual"; + setting.setIpConfigType(IPADDRESS_V6, CONFIG_IP_MANUAL); + isChanged = true; + } + if(info.strIPV6Address != ipv6AddressEdit->text() + || info.iIPV6Prefix != lengthEdit->text().toInt() + || info.strIPV6GateWay != gateWayEdit->text() + || info.strIPV6FirDns != firstDnsEdit->text() + || info.strIPV6SecDns != secondDnsEdit->text()) { + + qDebug() << "ipv6 info changed"; + QStringList dnsList; + dnsList.empty(); + if (!firstDnsEdit->text().isEmpty()) { + dnsList << firstDnsEdit->text(); + if (!secondDnsEdit->text().isEmpty()) { + dnsList << secondDnsEdit->text(); + } + } + + QString ipv6address =ipv6AddressEdit->text(); + QString prefix = lengthEdit->text(); + QString gateWay = gateWayEdit->text(); + setting.ipv6AddressConstruct(ipv6address, prefix, gateWay, dnsList); + setting.dumpInfo(); + isChanged = true; + } + } + return isChanged; +} + +void Ipv6Page::initUI() { + ipv6ConfigCombox = new QComboBox(this); + ipv6AddressEdit = new LineEdit(this); + lengthEdit = new LineEdit(this); + gateWayEdit = new LineEdit(this); + firstDnsEdit = new LineEdit(this); + secondDnsEdit = new LineEdit(this); + + m_configLabel = new QLabel(this); + m_addressLabel = new QLabel(this); + m_subnetLabel = new QLabel(this); + m_gateWayLabel = new QLabel(this); + m_dnsLabel = new QLabel(this); + m_secDnsLabel = new QLabel(this); + + + m_configLabel->setText(tr("Ipv6Config")); + m_addressLabel->setText(tr("Address")); + m_subnetLabel->setText(tr("Subnet prefix Length")); + m_gateWayLabel->setText(tr("Default Gateway")); + m_dnsLabel->setText(tr("Prefs DNS")); + m_secDnsLabel->setText(tr("Alternative DNS")); + + + m_detailLayout = new QFormLayout(this); + m_detailLayout->addRow(m_configLabel,ipv6ConfigCombox); + m_detailLayout->addRow(m_addressLabel,ipv6AddressEdit); + m_detailLayout->addRow(m_subnetLabel,lengthEdit); + m_detailLayout->addRow(m_gateWayLabel,gateWayEdit); + m_detailLayout->addRow(m_dnsLabel,firstDnsEdit); + m_detailLayout->addRow(m_secDnsLabel,secondDnsEdit); + + ipv6ConfigCombox->addItem(tr("Auto(DHCP)")); //"自动(DHCP)" + ipv6ConfigCombox->addItem(tr("Manual")); //"手动" + + QRegExp ipv6_rx("^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*$"); + ipv6AddressEdit->setValidator(new QRegExpValidator(ipv6_rx, this)); + gateWayEdit->setValidator(new QRegExpValidator(ipv6_rx, this)); + firstDnsEdit->setValidator(new QRegExpValidator(ipv6_rx, this)); + secondDnsEdit->setValidator(new QRegExpValidator(ipv6_rx, this)); + + QRegExp prefix_rx("\\b(?:(?:12[0-8]|1[0-1][0-9]|^[1-9][0-9]?$)\\.){3}(?:12[0-8]|1[0-1][0-9]|^[1-9][0-9]?$)\\b"); + lengthEdit->setValidator(new QRegExpValidator(prefix_rx,this)); +} + +void Ipv6Page::initComponent() { + if (ipv6ConfigCombox->currentIndex() == AUTO_CONFIG) { + setControlEnabled(false); + } else if (ipv6ConfigCombox->currentIndex() == MANUAL_CONFIG) { + setControlEnabled(true); + } + connect(ipv6ConfigCombox, SIGNAL(currentIndexChanged(int)), this, SLOT(configChanged(int))); + + connect(ipv6ConfigCombox, SIGNAL(currentIndexChanged(int)), this, SLOT(setEnableOfSaveBtn())); + connect(ipv6AddressEdit, SIGNAL(textChanged(QString)), this, SLOT(setEnableOfSaveBtn())); + connect(lengthEdit, SIGNAL(textChanged(QString)), this, SLOT(setEnableOfSaveBtn())); + connect(gateWayEdit, SIGNAL(textChanged(QString)), this, SLOT(setEnableOfSaveBtn())); + connect(firstDnsEdit, SIGNAL(textChanged(QString)), this, SLOT(setEnableOfSaveBtn())); + connect(secondDnsEdit, SIGNAL(textChanged(QString)), this, SLOT(setEnableOfSaveBtn())); +} + +void Ipv6Page::configChanged(int index) { + if (index == AUTO_CONFIG) { + setControlEnabled(false); + } + if (index == MANUAL_CONFIG) { + setControlEnabled(true); + } +} + +void Ipv6Page::setControlEnabled(bool check) +{ + ipv6AddressEdit->setEnabled(check); + lengthEdit->setEnabled(check); + gateWayEdit->setEnabled(check); + firstDnsEdit->setEnabled(check); + secondDnsEdit->setEnabled(check); + + if (!check) { + ipv6AddressEdit->clear(); + lengthEdit->clear(); + gateWayEdit->clear(); + firstDnsEdit->clear(); + secondDnsEdit->clear(); + } +} + +void Ipv6Page::setEnableOfSaveBtn() +{ + emit setIpv6PageState(checkConnectBtnIsEnabled()); +} + +bool Ipv6Page::checkConnectBtnIsEnabled() +{ + if (ipv6ConfigCombox->currentIndex() == AUTO_CONFIG) { + return true; + } else { + if (ipv6AddressEdit->text().isEmpty() || !getIpv6EditState(ipv6AddressEdit->text())) { + qDebug() << "ipv6address empty or invalid"; + return false; + } + + if (lengthEdit->text().isEmpty()) { + qDebug() << "ipv6 prefix length empty"; + return false; + } + + if (gateWayEdit->text().isEmpty() || !getIpv6EditState(gateWayEdit->text())) { + qDebug() << "ipv6 gateway empty or invalid"; + return false; + } + + if (firstDnsEdit->text().isEmpty() && !secondDnsEdit->text().isEmpty()) { + qDebug() << "ipv6 dns sort invalid"; + return false; + } + + if (!getIpv6EditState(firstDnsEdit->text())) { + qDebug() << "ipv6 first dns invalid"; + return false; + } + + if (!getIpv6EditState(secondDnsEdit->text())) { + qDebug() << "ipv6 second dns invalid"; + return false; + } + } + return true; +} + +bool Ipv6Page::getIpv6EditState(QString text) +{ + if (text.isEmpty()) { + return true; + } + QRegExp rx("^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*$"); + + bool match = false; + match = rx.exactMatch(text); + + return match; +} + +int Ipv6Page::getPerfixLength(QString text) +{ + qDebug() << "getPerfixLength" << text; + int length = 0; + QStringList list= text.split(":"); + for (int i = 0; i < list.size(); ++i) { + QString temp = list.at(i); + if (temp.isEmpty()) { + continue; + } + bool ok; + unsigned int val = temp.toUInt(&ok, 16); + temp = temp.setNum(val,2); + for(int j = 0; j < temp.length(); ++j) { + if (temp.at(j) == "1") { + length++; + } + } + } + qDebug() << "getPerfixLength" << length; + return length; +} + diff --git a/src/frontend/netdetails/ipv6page.h b/src/frontend/netdetails/ipv6page.h new file mode 100644 index 00000000..5e8d430d --- /dev/null +++ b/src/frontend/netdetails/ipv6page.h @@ -0,0 +1,66 @@ +#ifndef IPV6PAGE_H +#define IPV6PAGE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#include "kylinconnectsetting.h" +#include "coninfo.h" + +class Ipv6Page : public QFrame +{ + Q_OBJECT +public: + Ipv6Page(QWidget *parent = nullptr); + void setIpv6Config(KyIpConfigType ipv6Config); + void setIpv6(const QString &ipv4); + void setIpv6Perfix(const int &ipv6Perfix); + void setIpv6FirDns(const QString &ipv6FirDns); + void setIpv6SecDns(const QString &ipv6SecDns); + void setGateWay(const QString &gateWay); + + bool checkIsChanged(const ConInfo info, KyConnectSetting &setting); + + int getPerfixLength(QString text); + +public: + QComboBox *ipv6ConfigCombox; + LineEdit *ipv6AddressEdit; + LineEdit *lengthEdit; + LineEdit *gateWayEdit; + LineEdit *firstDnsEdit; + LineEdit *secondDnsEdit; +private: + QFormLayout *m_detailLayout; + QLabel *m_configLabel; + QLabel *m_addressLabel; + QLabel *m_subnetLabel; + QLabel *m_gateWayLabel; + QLabel *m_dnsLabel; + QLabel *m_secDnsLabel; +private: + void initUI(); + void initComponent(); + void setControlEnabled(bool check); + + bool getIpv6EditState(QString text); + + bool checkConnectBtnIsEnabled(); + +private slots: + void configChanged(int index); + void setEnableOfSaveBtn(); + +signals: + void setIpv6PageState(bool); +}; + +#endif // IPV6PAGE_H diff --git a/src/frontend/netdetails/netdetail.cpp b/src/frontend/netdetails/netdetail.cpp new file mode 100644 index 00000000..2c276407 --- /dev/null +++ b/src/frontend/netdetails/netdetail.cpp @@ -0,0 +1,964 @@ +#include "netdetail.h" +#include "backend/kylinipv4arping.h" +#include "backend/kylinipv6arping.h" +//#include "xatom/xatom-helper.h" + + +#define THEME_SCHAME "org.ukui.style" +#define COLOR_THEME "styleName" + +#include +#include +#include + +#define WINDOW_WIDTH 520 +#define WINDOW_HEIGHT 590 +#define BUTTON_SIZE 30 +#define ICON_SIZE 22,22 +#define TITLE_LAYOUT_MARGINS 9,9,0,0 +#define LAYOUT_MARGINS 24,0,24,0 +#define BOTTOM_LAYOUT_SPACING 16 +#define PAGE_LAYOUT_SPACING 1 +#define DETAIL_PAGE_NUM 0 +#define IPV4_PAGE_NUM 1 +#define IPV6_PAGE_NUM 2 +#define SECURITY_PAGE_NUM 3 +#define CREATE_NET_PAGE_NUM 4 +#define PAGE_MIN_HEIGHT 40 + +//extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); + +void NetDetail::showDesktopNotify(const QString &message) +{ + QDBusInterface iface("org.freedesktop.Notifications", + "/org/freedesktop/Notifications", + "org.freedesktop.Notifications", + QDBusConnection::sessionBus()); + QList args; + args<<(tr("Kylin NM")) + <<((unsigned int) 0) + <setEnabled(on); + ipv4Page->setEnabled(on); + ipv6Page->setEnabled(on); + securityPage->setEnabled(on); + createNetPage->setEnabled(on); + cancelBtn->setEnabled(on); + forgetBtn->setEnabled(on); + confimBtn->setEnabled(on); +} + +NetDetail::NetDetail(QString interface, QString name, QString uuid, bool isActive, bool isWlan, bool isCreateNet, QWidget *parent) + :m_deviceName(interface), + m_name(name), + m_uuid(uuid), + isActive(isActive), + isWlan(isWlan), + m_isCreateNet(isCreateNet), + QWidget(parent) +{ + //设置窗口无边框,阴影 +//#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) +// MotifWmHints window_hints; +// window_hints.flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS; +// window_hints.functions = MWM_FUNC_ALL; +// window_hints.decorations = MWM_DECOR_BORDER; +// XAtomHelper::getInstance()->setWindowMotifHint(this->winId(), window_hints); +//#else +// this->setWindowFlags(Qt::Dialog /*| Qt::FramelessWindowHint*/); + this->setWindowFlag(Qt::Window); +//#endif +// this->setProperty("useStyleWindowManager", false); //禁用拖动 +// setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint ); +// setAttribute(Qt::WA_TranslucentBackground); + setAttribute(Qt::WA_DeleteOnClose); + setFixedSize(WINDOW_WIDTH,WINDOW_HEIGHT); + centerToScreen(); + + qDebug() << m_isCreateNet << name; + if (!m_isCreateNet && name.isEmpty()) { + m_isCreateNet = true; + } + qDebug() << m_isCreateNet; + m_netDeviceResource = new KyNetworkDeviceResourse(this); + m_wirelessConnOpration = new KyWirelessConnectOperation(this); + m_resource = new KyWirelessNetResource(this); + m_connectOperation = new KyConnectOperation(this); + m_wiredConnOperation = new KyWiredConnectOperation(this); + initUI(); + loadPage(); + initComponent(); + getConInfo(m_info); + pagePadding(name,isWlan); + + connect(qApp, &QApplication::paletteChanged, this, &NetDetail::onPaletteChanged); + + isCreateOk = !(m_isCreateNet && !isWlan); + isDetailOk = !(m_name.isEmpty()); + isIpv4Ok = true; + isIpv6Ok = true; + isSecuOk = false; + if (!m_uuid.isEmpty() || (m_uuid.isEmpty() && m_info.secType == NONE)) { + isSecuOk = true; + } + + qDebug() << interface << name << uuid << "isWlan" << isWlan << "isCreateNet" <palette(); + + QGSettings * styleGsettings = nullptr; + const QByteArray style_id(THEME_SCHAME); + if (QGSettings::isSchemaInstalled(style_id)) { + styleGsettings = new QGSettings(style_id); + QString currentTheme = styleGsettings->get(COLOR_THEME).toString(); + if(currentTheme == "ukui-default"){ + pal = lightPalette(this); + } + } + + this->setPalette(pal); + + setFramePalette(detailPage, pal); + setFramePalette(ipv4Page, pal); + setFramePalette(ipv6Page, pal); + setFramePalette(securityPage, pal); + setFramePalette(createNetPage, pal); + QToolTip::setPalette(pal); + + QPalette listwidget_pal(detailPage->m_listWidget->palette()); + listwidget_pal.setColor(QPalette::Base, this->palette().base().color()); + listwidget_pal.setColor(QPalette::AlternateBase, this->palette().alternateBase().color()); + detailPage->m_listWidget->setAlternatingRowColors(true); + detailPage->m_listWidget->setPalette(listwidget_pal); + + if (styleGsettings != nullptr) { + delete styleGsettings; + styleGsettings = nullptr; + } +} + +void NetDetail::paintEvent(QPaintEvent *event) +{ + return QWidget::paintEvent(event); +} + +void NetDetail::closeEvent(QCloseEvent *event) +{ + emit this->detailPageClose(false); + emit this->createPageClose(m_deviceName); + return QWidget::closeEvent(event); +} + +void NetDetail::centerToScreen() +{ + QDesktopWidget* m = QApplication::desktop(); + QRect desk_rect = m->screenGeometry(m->screenNumber(QCursor::pos())); + int desk_x = desk_rect.width(); + int desk_y = desk_rect.height(); + int x = this->width(); + int y = this->height(); + this->move(desk_x / 2 - x / 2 + desk_rect.left(), desk_y / 2 - y / 2 + desk_rect.top()); +} + +void NetDetail::initUI() +{ + QVBoxLayout *mainLayout = new QVBoxLayout(this); + mainLayout->setContentsMargins(9,9,14,24); + + detailPage = new DetailPage(isWlan, m_name.isEmpty(), this); + + ipv4Page = new Ipv4Page(this); + ipv6Page = new Ipv6Page(this); + securityPage = new SecurityPage(this); + createNetPage = new CreatNetPage(this); + + this->installEventFilter(this); + + centerWidget = new QWidget(this); + bottomWidget = new QWidget(this); + + stackWidget = new QStackedWidget(centerWidget); + stackWidget->addWidget(detailPage); + stackWidget->addWidget(ipv4Page); + stackWidget->addWidget(ipv6Page); + stackWidget->addWidget(securityPage); + stackWidget->addWidget(createNetPage); + + mainLayout->addWidget(centerWidget); + mainLayout->addWidget(bottomWidget); + + bottomWidget->setMinimumHeight(PAGE_MIN_HEIGHT); + + pageFrame = new QFrame(this); + + QHBoxLayout *pageLayout = new QHBoxLayout(pageFrame); + pageLayout->setSpacing(PAGE_LAYOUT_SPACING); + + detailBtn = new QPushButton(this); + detailBtn->setText(tr("Detail")); + detailBtn->setCheckable(true); + detailBtn->setChecked(true); + + ipv4Btn = new QPushButton(this); + ipv4Btn->setText(tr("Ipv4")); + ipv4Btn->setCheckable(true); + + ipv6Btn = new QPushButton(this); + ipv6Btn->setText(tr("Ipv6")); + ipv6Btn->setCheckable(true); + + securityBtn = new QPushButton(this); + securityBtn->setText(tr("Security")); + securityBtn->setCheckable(true); + + m_group = new QButtonGroup(this); + m_group->addButton(detailBtn); + m_group->addButton(ipv4Btn); + m_group->addButton(ipv6Btn); + if (isWlan) { + m_group->addButton(securityBtn); + } + + pageLayout->addStretch(); + pageLayout->addWidget(detailBtn); + pageLayout->addWidget(ipv4Btn); + pageLayout->addWidget(ipv6Btn); + pageLayout->addWidget(securityBtn); + pageLayout->addStretch(); + + confimBtn = new QPushButton(this); + confimBtn->setText(tr("Confirm")); + + cancelBtn = new QPushButton(this); + cancelBtn->setText(tr("Cancel")); + + forgetBtn = new QPushButton(this); + forgetBtn->setText(tr("Forget this network")); + + this->setWindowIcon(QIcon::fromTheme("kylin-network")); + + QVBoxLayout *centerlayout = new QVBoxLayout(centerWidget); + centerlayout->setContentsMargins(LAYOUT_MARGINS); + centerlayout->addWidget(pageFrame); + centerlayout->addWidget(stackWidget); + + QHBoxLayout *bottomLayout = new QHBoxLayout(bottomWidget); + bottomLayout->setContentsMargins(LAYOUT_MARGINS); + bottomLayout->setSpacing(BOTTOM_LAYOUT_SPACING); + bottomLayout->addWidget(forgetBtn); + bottomLayout->addStretch(); + bottomLayout->addWidget(cancelBtn); + bottomLayout->addWidget(confimBtn); + +// QPalette pal(this->palette()); +// pal.setColor(QPalette::Background, qApp->palette().base().color()); + this->setAutoFillBackground(true); +// this->setPalette(pal); + onPaletteChanged(); +} + +void NetDetail::loadPage() +{ + //判断是否创建网络页面 + if (m_isCreateNet && !isWlan) { + pageFrame->hide(); + stackWidget->setCurrentIndex(CREATE_NET_PAGE_NUM); + this->setWindowTitle(tr("Add Lan Connect")); + } else { + stackWidget->setCurrentIndex(DETAIL_PAGE_NUM); + this->setWindowTitle(m_name); + if (!isWlan) { + securityBtn->hide(); + } else { + securityBtn->show(); + if (m_name.isEmpty()) { + this->setWindowTitle(tr("connect hiddin wlan")); + } + } + } +} + +void NetDetail::initComponent() +{ + connect(cancelBtn, &QPushButton::clicked, this, [=] { + close(); + }); + connect(detailBtn, &QPushButton::clicked, this, [=] { + stackWidget->setCurrentIndex(DETAIL_PAGE_NUM); + }); + connect(ipv4Btn, &QPushButton::clicked, this, [=] { + stackWidget->setCurrentIndex(IPV4_PAGE_NUM); + }); + connect(ipv6Btn, &QPushButton::clicked, this, [=] { + stackWidget->setCurrentIndex(IPV6_PAGE_NUM); + }); + connect(securityBtn, &QPushButton::clicked, this, [=] { + stackWidget->setCurrentIndex(SECURITY_PAGE_NUM); + }); + connect(confimBtn, SIGNAL(clicked()), this, SLOT(on_btnConfirm_clicked())); + if (isWlan && !m_uuid.isEmpty()) { + forgetBtn->show(); + connect(forgetBtn, SIGNAL(clicked()), this, SLOT(on_btnForget_clicked())); + } else { + forgetBtn->hide(); + } + + connect(createNetPage, &CreatNetPage::setCreatePageState, this, [=](bool status) { + isCreateOk = status; + setConfirmEnable(); + }); + + connect(detailPage, &DetailPage::setDetailPageState, this, [=](bool status) { + isDetailOk = status; + setConfirmEnable(); + }); + + connect(ipv4Page, &Ipv4Page::setIpv4PageState, this, [=](bool status) { + isIpv4Ok = status; + setConfirmEnable(); + }); + + connect(ipv6Page, &Ipv6Page::setIpv6PageState, this, [=](bool status) { + isIpv6Ok = status; + setConfirmEnable(); + }); + + connect(securityPage, &SecurityPage::setSecuPageState, this, [=](bool status) { + isSecuOk = status; + setConfirmEnable(); + }); +} + +void NetDetail::pagePadding(QString netName, bool isWlan) +{ + //网络详情页填充 + if(m_isCreateNet && !isWlan) { + return; + } + + detailPage->setSSID(netName); + detailPage->setProtocol(m_info.strConType); + detailPage->setSecType(m_info.strSecType); + detailPage->setHz(m_info.strHz); + detailPage->setChan(m_info.strChan); + detailPage->setIpv4(m_info.strDynamicIpv4); + detailPage->setIpv4Dns(m_info.strDynamicIpv4Dns); + detailPage->setIpv6(m_info.strDynamicIpv6); + detailPage->setMac(m_info.strMac); + detailPage->setBandWidth(m_info.strBandWidth); + detailPage->setAutoConnect(m_info.isAutoConnect); + + //ipv4页面填充 + if (m_info.ipv4ConfigType == CONFIG_IP_MANUAL) { + ipv4Page->setIpv4Config(m_info.ipv4ConfigType); + ipv4Page->setIpv4(m_info.strIPV4Address); + ipv4Page->setNetMask(m_info.strIPV4NetMask); + ipv4Page->setIpv4FirDns(m_info.strIPV4FirDns); + ipv4Page->setIpv4SecDns(m_info.strIPV4SecDns); + ipv4Page->setGateWay(m_info.strIPV4GateWay); + } else { + ipv4Page->setIpv4Config(m_info.ipv4ConfigType); + } + //ipv6页面填充 + if (m_info.ipv6ConfigType == CONFIG_IP_MANUAL) { + ipv6Page->setIpv6Config(m_info.ipv6ConfigType); + ipv6Page->setIpv6(m_info.strIPV6Address); + ipv6Page->setIpv6Perfix(m_info.iIPV6Prefix); + ipv6Page->setIpv6FirDns(m_info.strIPV6FirDns); + ipv6Page->setIpv6SecDns(m_info.strIPV6SecDns); + ipv6Page->setGateWay(m_info.strIPV6GateWay); + } else { + ipv6Page->setIpv6Config(m_info.ipv6ConfigType); + } + + //安全页面 + if (isWlan) { + securityPage->setSecurity(m_info.secType); + qDebug() << "setSecurity" << m_info.secType; + if (m_info.secType == WPA_AND_WPA2_ENTERPRISE) { + if (m_info.enterpriseType == TLS) { + securityPage->setTlsInfo(m_info.tlsInfo); + } else if (m_info.enterpriseType == PEAP) { + securityPage->setPeapInfo(m_info.peapInfo); + } else if (m_info.enterpriseType == TTLS) { + securityPage->setTtlsInfo(m_info.ttlsInfo); + } + } + } + +} + +//获取网路详情信息 +void NetDetail::getConInfo(ConInfo &conInfo) +{ + if (m_isCreateNet && !isWlan) { + return; + } + getBaseInfo(conInfo); + getDynamicIpInfo(conInfo, isActive); + getStaticIpInfo(conInfo,isActive); +} + + +//详情ssid 带宽 物理地址 无线额外(安全性 频带 通道) +void NetDetail::getBaseInfo(ConInfo &conInfo) +{ + //有线无线公有 + conInfo.strConName = m_name; + + QString hardAddress; + int bandWith; + m_netDeviceResource->getHardwareInfo(m_deviceName, hardAddress, bandWith); + + if (!hardAddress.isEmpty()) { + conInfo.strBandWidth = QString("%1").arg(bandWith/1000) + "Mbps"; + conInfo.strMac = hardAddress; + } + + if (!isWlan) { + conInfo.strConType = "802-3-ethernet"; + } else { + conInfo.strConType = "802-11-wireless"; + if (!isActive) { + KyWirelessNetItem item; + if (!m_resource->getWifiNetwork(m_deviceName, m_name, item)) { + qDebug() << "getWifiNetWork failed device:" << m_deviceName << " name:" << m_name; + return; + } else { + conInfo.strHz = QString::number(item.m_frequency); + conInfo.strChan = QString::number(item.m_channel); + //无线特有 + conInfo.strSecType = item.m_secuType; + if (conInfo.strSecType.isEmpty()) { + conInfo.strSecType = tr("None"); + } + + if (!item.m_isConfigured) { + conInfo.secType = item.m_kySecuType; + } + } + } else { + uint iHz,iChan; + QString strMac; + m_netDeviceResource->getDeviceActiveAPInfo(m_deviceName, strMac, iHz, iChan, conInfo.strSecType); + if (conInfo.strSecType.isEmpty()) { + conInfo.strSecType = tr("None"); + } + conInfo.strHz = QString::number(iHz); + conInfo.strChan = QString::number(iChan); + + } + + + + KyKeyMgmt type = m_wirelessConnOpration->getConnectKeyMgmt(m_uuid); + if (!m_uuid.isEmpty()) { + KyKeyMgmt type = m_wirelessConnOpration->getConnectKeyMgmt(m_uuid); + if (type == WpaNone || type == Unknown) { + conInfo.secType = NONE; + } else if (type == WpaPsk) { + conInfo.secType = WPA_AND_WPA2_PERSONAL; + } else if (type == SAE) { + conInfo.secType = WPA3_PERSONAL; + } else if (type == WpaEap) { + conInfo.secType = WPA_AND_WPA2_ENTERPRISE; + } else { + qDebug() << "KeyMgmt not support now " << type; + } + } + + initSecuData(); + } +} + +//详情ipv4 ipv6 ipv4Dns +void NetDetail::getDynamicIpInfo(ConInfo &conInfo, bool bActived) +{ + if (!bActived) { + return; + } + //已激活的网络 详情页显示动态ipv4 ipv6 dns + QString ipv4,ipv6; + QList ipv4Dns,ipv6Dns; + KyActiveConnectResourse *activeResourse = new KyActiveConnectResourse(this); + activeResourse->getActiveConnectIpInfo(m_uuid,ipv4,ipv6); + activeResourse->getActiveConnectDnsInfo(m_uuid,ipv4Dns,ipv6Dns); + + //Ipv6 + if (!ipv6.isEmpty()) { + conInfo.strDynamicIpv6 = ipv6; + } + + //IPv4 + if (!ipv4.isEmpty()) { + conInfo.strDynamicIpv4 = ipv4; + } + + if (!ipv4Dns.isEmpty()) { + conInfo.strDynamicIpv4Dns = ipv4Dns.at(0).toString(); + } +} + +//ipv4+ipv6页面 +void NetDetail::getStaticIpInfo(ConInfo &conInfo, bool bActived) +{ + KyConnectResourse *kyConnectResourse = new KyConnectResourse(this); + KyConnectSetting connetSetting; + kyConnectResourse->getConnectionSetting(m_uuid,connetSetting); + connetSetting.dumpInfo(); + + conInfo.ipv4ConfigType = connetSetting.m_ipv4ConfigIpType; + conInfo.ipv6ConfigType = connetSetting.m_ipv6ConfigIpType; + conInfo.isAutoConnect = connetSetting.m_isAutoConnect; + + if (connetSetting.m_ipv4ConfigIpType == CONFIG_IP_MANUAL) { + if (connetSetting.m_ipv4Address.size() > 0) { + conInfo.strIPV4Address = connetSetting.m_ipv4Address.at(0).ip().toString(); + conInfo.strIPV4NetMask = connetSetting.m_ipv4Address.at(0).netmask().toString(); + conInfo.strIPV4GateWay = connetSetting.m_ipv4Address.at(0).gateway().toString(); + } + if (connetSetting.m_ipv4Dns.size() == 1) { + conInfo.strIPV4FirDns = connetSetting.m_ipv4Dns.at(0).toString(); + } else if (connetSetting.m_ipv4Dns.size() > 1) { + conInfo.strIPV4FirDns = connetSetting.m_ipv4Dns.at(0).toString(); + conInfo.strIPV4SecDns = connetSetting.m_ipv4Dns.at(1).toString(); + } + } + + if (connetSetting.m_ipv6ConfigIpType == CONFIG_IP_MANUAL) { + if (connetSetting.m_ipv6Address.size() > 0) { + conInfo.strIPV6Address = connetSetting.m_ipv6Address.at(0).ip().toString(); + conInfo.iIPV6Prefix = ipv6Page->getPerfixLength(connetSetting.m_ipv6Address.at(0).netmask().toString()); + conInfo.strIPV6GateWay = connetSetting.m_ipv6Address.at(0).gateway().toString(); + } + + if (connetSetting.m_ipv6Dns.size() == 1) { + conInfo.strIPV6FirDns = connetSetting.m_ipv6Dns.at(0).toString(); + } else if (connetSetting.m_ipv4Dns.size() > 1) { + conInfo.strIPV6FirDns = connetSetting.m_ipv6Dns.at(0).toString(); + conInfo.strIPV6SecDns = connetSetting.m_ipv6Dns.at(1).toString(); + } + } + + if (!bActived) { + conInfo.strDynamicIpv4 = conInfo.strIPV4Address.isEmpty() ? tr("Auto") : conInfo.strIPV4Address; + conInfo.strDynamicIpv6 = conInfo.strIPV6Address.isEmpty() ? tr("Auto") : conInfo.strIPV6Address; + conInfo.strDynamicIpv4Dns = conInfo.strIPV4FirDns.isEmpty() ? tr("Auto") : conInfo.strIPV4FirDns; + } +} + +void NetDetail::initSecuData() +{ + QString password(""); + int type = m_info.secType; + switch (type) { + case NONE: + break; + case WPA_AND_WPA2_PERSONAL: + case WPA3_PERSONAL: + if (!m_uuid.isEmpty()) { + NetworkManager::Setting::SecretFlags flag; + if (m_wirelessConnOpration->getConnSecretFlags(m_uuid, flag)) { + if (!flag) { + password = m_wirelessConnOpration->getPsk(m_uuid); + } + } + } + m_info.strPassword = password; + securityPage->setPsk(password); + break; + case WPA_AND_WPA2_ENTERPRISE: + if (!m_wirelessConnOpration->getEnterpiseEapMethod(m_uuid, m_info.enterpriseType)) { + qDebug() << m_name << "not enterprise wifi"; + } else if (m_info.enterpriseType == TLS){ + initTlsInfo(m_info); + } else if (m_info.enterpriseType == PEAP){ + initPeapInfo(m_info); + } else { + initTtlsInfo(m_info); + } + break; + default: + break; + } +} + +void NetDetail::initTlsInfo(ConInfo &conInfo) +{ + m_resource->getEnterPriseInfoTls(m_uuid, conInfo.tlsInfo); +} + +void NetDetail::initPeapInfo(ConInfo &conInfo) +{ + m_resource->getEnterPriseInfoPeap(m_uuid, conInfo.peapInfo); +} + +void NetDetail::initTtlsInfo(ConInfo &conInfo) +{ + m_resource->getEnterPriseInfoTtls(m_uuid, conInfo.ttlsInfo); +} + +//点击了保存更改网络设置的按钮 +void NetDetail::on_btnConfirm_clicked() +{ + qDebug() << "on_btnConfirm_clicked"; + setNetdetailSomeEnable(false); + if (m_isCreateNet) { + if (!isWlan) { + //新建有线连接 + qDebug() << "Confirm create wired connect"; + if (!createWiredConnect()) { + setNetdetailSomeEnable(true); + return; + } + } else { + //新建无线连接 + qDebug() << "Confirm create wireless connect"; + if (!createWirelessConnect()) { + setNetdetailSomeEnable(true); + return; + } + } + } else { + //更新连接 + qDebug() << "Confirm update connect"; + if (!updateConnect()) { + setNetdetailSomeEnable(true); + return; + } + } + close(); +} + +//点击忘记网络 +void NetDetail::on_btnForget_clicked() +{ + qDebug() << "user choose forget connection uuid = " << m_uuid; + m_connectOperation->deleteConnect(m_uuid); + close(); +} + +void NetDetail::setConfirmEnable() +{ + if (m_isCreateNet && !isWlan) { + isConfirmBtnEnable = isCreateOk; + } else { + if (isDetailOk && isIpv4Ok && isIpv6Ok) { + if (isWlan && !isSecuOk) { + isConfirmBtnEnable = false; + } else { + isConfirmBtnEnable = true; + } + } else { + isConfirmBtnEnable = false; + } + } + qDebug() << "setConfirmEnable "<< isConfirmBtnEnable; + confimBtn->setEnabled(isConfirmBtnEnable); +} + +bool NetDetail::checkIpv4Conflict(QString ipv4Address) +{ + showDesktopNotify(tr("start check ipv4 address conflict")); + bool isConflict = false; + KyIpv4Arping* ipv4Arping = new KyIpv4Arping(m_deviceName, ipv4Address); + + if (ipv4Arping->ipv4ConflictCheck() >= 0) { + isConflict = ipv4Arping->ipv4IsConflict(); + } else { + qWarning() << "checkIpv4Conflict internal error"; + } + + delete ipv4Arping; + ipv4Arping = nullptr; + return isConflict; +} + +bool NetDetail::checkIpv6Conflict(QString ipv6address) +{ + showDesktopNotify(tr("start check ipv6 address conflict")); + bool isConflict = false; + KyIpv6Arping* ipv46rping = new KyIpv6Arping(m_deviceName, ipv6address); + + if (ipv46rping->ipv6ConflictCheck() >= 0) { + isConflict = ipv46rping->ipv6IsConflict(); + } else { + qWarning() << "checkIpv6Conflict internal error"; + } + + delete ipv46rping; + ipv46rping = nullptr; + return isConflict; +} + +void NetDetail::updateWirelessPersonalConnect() +{ + KyWirelessConnectSetting setting; + securityPage->updateSecurityChange(setting); + bool isPwdChanged = !(m_info.strPassword == setting.m_psk); + m_wirelessConnOpration->updateWirelessPersonalConnect(m_uuid, setting, isPwdChanged); +} + +void NetDetail::updateWirelessEnterPriseConnect(KyEapMethodType enterpriseType) +{ + if (enterpriseType == TLS) { + m_info.tlsInfo.devIfaceName = m_deviceName; + securityPage->updateTlsChange(m_info.tlsInfo); + m_wirelessConnOpration->updateWirelessEnterPriseTlsConnect(m_uuid, m_info.tlsInfo); + } else if (enterpriseType == PEAP) { + securityPage->updatePeapChange(m_info.peapInfo); + m_wirelessConnOpration->updateWirelessEnterPrisePeapConnect(m_uuid, m_info.peapInfo); + } else if (enterpriseType == TTLS) { + securityPage->updateTtlsChange(m_info.ttlsInfo); + m_wirelessConnOpration->updateWirelessEnterPriseTtlsConnect(m_uuid, m_info.ttlsInfo); + } +} + +bool NetDetail::createWiredConnect() +{ + KyWirelessConnectSetting connetSetting; + connetSetting.setIfaceName(m_deviceName); + createNetPage->constructIpv4Info(connetSetting); + if (connetSetting.m_ipv4ConfigIpType != CONFIG_IP_DHCP) { + if (checkIpv4Conflict(connetSetting.m_ipv4Address.at(0).ip().toString())) { + qDebug() << "ipv4 conflict"; + showDesktopNotify(tr("ipv4 address conflict!")); + return false; + } + } + m_wiredConnOperation->createWiredConnect(connetSetting); + return true; +} + +bool NetDetail::createWirelessConnect() +{ + KyWirelessConnectSetting connetSetting; + KySecuType secuType; + KyEapMethodType enterpriseType; + securityPage->getSecuType(secuType, enterpriseType); + //类型判断 + if (!m_name.isEmpty()) { + if (!checkWirelessSecurity(secuType)) { + return false; + } + } + + //基本信息 + QString ssid; + if (m_name.isEmpty()) { + detailPage->getSsid(ssid); + } else { + ssid = m_name; + } + connetSetting.setConnectName(ssid); + connetSetting.setIfaceName(m_deviceName); + if (detailPage->checkIsChanged(m_info)) { + connetSetting.isAutoConnect = !m_info.isAutoConnect; + } else { + connetSetting.isAutoConnect = m_info.isAutoConnect; + } + qDebug() << "isAutoConnect" << connetSetting.isAutoConnect; + connetSetting.m_ssid = ssid; +// connetSetting.m_secretFlag = NetworkManager::Setting::None; + //由于X.h的None与此处的None有歧义,此处直接使用值 + connetSetting.m_secretFlag = 0; + + //ipv4 & ipv6 + bool ipv4Change = ipv4Page->checkIsChanged(m_info, connetSetting); + bool ipv6Change = ipv6Page->checkIsChanged(m_info, connetSetting); + + connetSetting.dumpInfo(); + + qDebug() << "ipv4Changed" << ipv4Change << "ipv6Change" << ipv6Change; + if (ipv4Change && connetSetting.m_ipv4ConfigIpType == CONFIG_IP_MANUAL) { + if (checkIpv4Conflict(connetSetting.m_ipv4Address.at(0).ip().toString())) { + qDebug() << "ipv4 conflict"; + showDesktopNotify(tr("ipv4 address conflict!")); + return false; + } + } + + if (ipv6Change && connetSetting.m_ipv6ConfigIpType == CONFIG_IP_MANUAL) { + if (checkIpv6Conflict(connetSetting.m_ipv6Address.at(0).ip().toString())) { + qDebug() << "ipv6 conflict"; + showDesktopNotify(tr("ipv6 address conflict!")); + return false; + } + } + //wifi安全性 + if (secuType == WPA_AND_WPA2_ENTERPRISE) { + connetSetting.m_type = WpaEap; + if (enterpriseType == TLS) { + m_info.tlsInfo.devIfaceName = m_deviceName; + securityPage->updateTlsChange(m_info.tlsInfo); + if (!m_name.isEmpty()) { + qDebug() << "add new TLS connect"; + m_wirelessConnOpration->addTlsConnect(connetSetting, m_info.tlsInfo); + } else { + qDebug() << "addAndConnect TLS connect"; + m_wirelessConnOpration->addAndActiveWirelessEnterPriseTlsConnect(m_info.tlsInfo, connetSetting, m_deviceName, true); + } + } else if (enterpriseType == PEAP) { + securityPage->updatePeapChange(m_info.peapInfo); + if (!m_name.isEmpty()) { + qDebug() << "add new PEAP connect"; + m_wirelessConnOpration->addPeapConnect(connetSetting, m_info.peapInfo); + } else { + qDebug() << "addAndConnect PEAP connect"; + m_wirelessConnOpration->addAndActiveWirelessEnterPrisePeapConnect(m_info.peapInfo, connetSetting, m_deviceName, true); + } + } else if (enterpriseType == TTLS) { + securityPage->updateTtlsChange(m_info.ttlsInfo); + if (!m_name.isEmpty()) { + qDebug() << "add new TTLS connect"; + m_wirelessConnOpration->addTtlsConnect(connetSetting, m_info.ttlsInfo); + } else { + qDebug() << "addAndConnect TTLS connect"; + m_wirelessConnOpration->addAndActiveWirelessEnterPriseTtlsConnect(m_info.ttlsInfo, connetSetting, m_deviceName, true); + } + } + } else { + securityPage->updateSecurityChange(connetSetting); + if (!m_name.isEmpty()) { + qDebug() << "add new personal connect"; + m_wirelessConnOpration->addConnect(connetSetting); + } else { + qDebug() << "addAndConnect personal connect" << m_deviceName; + m_wirelessConnOpration->addAndActiveWirelessConnect(m_deviceName, connetSetting, true); + } + } + return true; +} + +bool NetDetail::updateConnect() +{ + KyConnectResourse *kyConnectResourse = new KyConnectResourse(this); + KyConnectSetting connetSetting; + KySecuType secuType; + KyEapMethodType enterpriseType; + kyConnectResourse->getConnectionSetting(m_uuid,connetSetting); + + bool securityChange = false; + if (isWlan) { + securityChange = securityPage->checkIsChanged(m_info); + if(securityChange) { + securityPage->getSecuType(secuType, enterpriseType); + if (!checkWirelessSecurity(secuType)) { + return false; + } + } + } + + if(!m_uuid.isEmpty() && detailPage->checkIsChanged(m_info)) { + m_wirelessConnOpration->setWirelessAutoConnect(m_uuid, !m_info.isAutoConnect); + } + + bool ipv4Change = ipv4Page->checkIsChanged(m_info, connetSetting); + bool ipv6Change = ipv6Page->checkIsChanged(m_info, connetSetting); + + qDebug() << "ipv4Changed" << ipv4Change << "ipv6Change" << ipv6Change; + + if (ipv4Change && connetSetting.m_ipv4ConfigIpType == CONFIG_IP_MANUAL) { + if (checkIpv4Conflict(connetSetting.m_ipv4Address.at(0).ip().toString())) { + qDebug() << "ipv4 conflict"; + showDesktopNotify(tr("ipv4 address conflict!")); + return false; + } + } + + if (ipv6Change && connetSetting.m_ipv6ConfigIpType == CONFIG_IP_MANUAL) { + if (checkIpv6Conflict(connetSetting.m_ipv6Address.at(0).ip().toString())) { + qDebug() << "ipv6 conflict"; + showDesktopNotify(tr("ipv6 address conflict!")); + return false; + } + } + + if (ipv4Change || ipv6Change) { + connetSetting.dumpInfo(); + m_wiredConnOperation->updateWiredConnect(m_uuid, connetSetting); + } + + qDebug() << "securityChange" << securityChange; + if (securityChange) { + if (secuType == WPA_AND_WPA2_ENTERPRISE) { + updateWirelessEnterPriseConnect(enterpriseType); + } else { + updateWirelessPersonalConnect(); + } + } + + if (ipv4Change || ipv6Change || securityChange) { + if (isActive) { + //信息变化 断开-重连 更新需要時間 不可以立即重連 +// sleep(1); + QEventLoop eventloop; + QTimer::singleShot(1000, &eventloop, SLOT(quit())); + eventloop.exec(); + m_wirelessConnOpration->activateConnection(m_uuid, m_deviceName); + } + } + return true; +} + +bool NetDetail::checkWirelessSecurity(KySecuType secuType) +{ + if (secuType == WPA_AND_WPA2_ENTERPRISE) { + if(m_info.strSecType.indexOf("802.1X") < 0) { + showDesktopNotify(tr("this wifi no support enterprise type")); + return false; + } + } else { + if (secuType == NONE && m_info.strSecType != tr("None")) { + showDesktopNotify(tr("this wifi no support None type")); + return false; + } else if (secuType == WPA_AND_WPA2_PERSONAL + && (m_info.strSecType.indexOf("WPA1") < 0 && + m_info.strSecType.indexOf("WPA2") < 0)) { + showDesktopNotify(tr("this wifi no support WPA2 type")); + return false; + } else if (secuType == WPA3_PERSONAL && m_info.strSecType.indexOf("WPA3") < 0) { + showDesktopNotify(tr("this wifi no support WPA3 type")); + return false; + } + } + return true; +} + +bool NetDetail::eventFilter(QObject *w, QEvent *event) +{ + // 回车键触发确定按钮点击事件 + if (event->type() == QEvent::KeyPress) { + QKeyEvent *mEvent = static_cast(event); + if (mEvent->key() == Qt::Key_Enter || mEvent->key() == Qt::Key_Return) { + if (confimBtn->isEnabled()) { + emit confimBtn->clicked(); + } + return true; + } else if (mEvent->key() == Qt::Key_Escape) { + close(); + return true; + } + } + return QWidget::eventFilter(w, event); +} diff --git a/src/frontend/netdetails/netdetail.h b/src/frontend/netdetails/netdetail.h new file mode 100644 index 00000000..c465527c --- /dev/null +++ b/src/frontend/netdetails/netdetail.h @@ -0,0 +1,141 @@ +#ifndef NETDETAIL_H +#define NETDETAIL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "detailpage.h" +#include "ipv4page.h" +#include "ipv6page.h" +#include "securitypage.h" +#include "creatnetpage.h" +#include "coninfo.h" +#include "tab-pages/tabpage.h" + +class NetDetail : public QWidget +{ + Q_OBJECT + +public: + NetDetail(QString interface, QString name, QString uuid, bool isActive, bool isWlan, bool isCreateNet, QWidget *parent = nullptr); + ~NetDetail(); +protected: + void paintEvent(QPaintEvent *event); + void closeEvent(QCloseEvent *event); + bool eventFilter(QObject *w, QEvent *event); + +private: + void initUI(); + void centerToScreen(); + void initComponent(); + void getConInfo(ConInfo &conInfo); + void loadPage(); + void pagePadding(QString netName, bool isWlan); + void initSecuData(); + + void initTlsInfo(ConInfo &conInfo); + void initPeapInfo(ConInfo &conInfo); + void initTtlsInfo(ConInfo &conInfo); + + void updateWirelessPersonalConnect(); + void updateWirelessEnterPriseConnect(KyEapMethodType enterpriseType); + + //详情ssid 带宽 物理地址 无线额外(安全性 频带 通道) + void getBaseInfo(ConInfo &conInfo); + //详情ipv4 ipv6 ipv4Dns + void getDynamicIpInfo(ConInfo &conInfo, bool bActived); + //ipv4+ipv6页面 + void getStaticIpInfo(ConInfo &conInfo, bool bActived); + + void setConfirmEnable(); + + bool checkIpv4Conflict(QString ipv4Address); + bool checkIpv6Conflict(QString ipv6Address); + + bool createWiredConnect(); + bool createWirelessConnect(); + bool updateConnect(); + + bool checkWirelessSecurity(KySecuType secuType); + + void showDesktopNotify(const QString &message); + + void setNetdetailSomeEnable(bool on); +private: + KyNetworkDeviceResourse *m_netDeviceResource = nullptr; + KyConnectOperation* m_connectOperation = nullptr; + KyWirelessConnectOperation *m_wirelessConnOpration = nullptr; + KyWiredConnectOperation *m_wiredConnOperation = nullptr; + KyWirelessNetResource *m_resource = nullptr; + + QStackedWidget * stackWidget; + + DetailPage * detailPage; + Ipv4Page * ipv4Page; + Ipv6Page * ipv6Page; + SecurityPage * securityPage; + CreatNetPage * createNetPage; + + QWidget * centerWidget; + QWidget * bottomWidget; + + QPushButton * cancelBtn; + QPushButton * forgetBtn; + QPushButton * confimBtn; + + QPushButton * detailBtn; + QPushButton * ipv4Btn; + QPushButton * ipv6Btn; + QPushButton * securityBtn; + QFrame * pageFrame; + + QString m_name; + QString m_uuid; + QString m_deviceName; + + bool isWlan; + bool m_isCreateNet; + bool isActive; + bool isHideWlan; + + bool isCreateOk; + bool isDetailOk; + bool isIpv4Ok; + bool isIpv6Ok; + bool isSecuOk; + bool isConfirmBtnEnable; + + ConInfo m_info; + + QButtonGroup *m_group; + +private slots: + void on_btnConfirm_clicked(); + void on_btnForget_clicked(); + void onPaletteChanged(); + +signals: + void detailPageClose(bool on); + void createPageClose(QString); +}; + + + +#endif // NETDETAIL_H diff --git a/src/frontend/netdetails/netdetails.pri b/src/frontend/netdetails/netdetails.pri new file mode 100644 index 00000000..720a66b8 --- /dev/null +++ b/src/frontend/netdetails/netdetails.pri @@ -0,0 +1,22 @@ +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/coninfo.h \ + $$PWD/creatnetpage.h \ + $$PWD/customtabstyle.h \ + $$PWD/detailpage.h \ + $$PWD/detailwidget.h \ + $$PWD/ipv4page.h \ + $$PWD/ipv6page.h \ + $$PWD/netdetail.h \ + $$PWD/securitypage.h + +SOURCES += \ + $$PWD/creatnetpage.cpp \ + $$PWD/customtabstyle.cpp \ + $$PWD/detailpage.cpp \ + $$PWD/detailwidget.cpp \ + $$PWD/ipv4page.cpp \ + $$PWD/ipv6page.cpp \ + $$PWD/netdetail.cpp \ + $$PWD/securitypage.cpp diff --git a/src/frontend/netdetails/securitypage.cpp b/src/frontend/netdetails/securitypage.cpp new file mode 100644 index 00000000..70845e28 --- /dev/null +++ b/src/frontend/netdetails/securitypage.cpp @@ -0,0 +1,834 @@ +#include "securitypage.h" +#include "netdetail.h" + +#include + +SecurityPage::SecurityPage(QWidget *parent) : QFrame(parent) +{ + initUI(); + initConnect(); +} + +void SecurityPage::initUI() +{ + secuTypeLabel = new QLabel(this); + pwdLabel = new QLabel(this); + secuTypeLabel = new QLabel(this); + pwdLabel = new QLabel(this); + //企业wifi共有 + eapTypeLabel = new QLabel(this); + //TLS + identityLable = new QLabel(this); + domainLable = new QLabel(this); + caCertPathLabel = new QLabel(this); + caNeedFlagLabel = new QLabel(this); + clientCertPathLabel = new QLabel(this); + clientPrivateKeyLabel = new QLabel(this); + clientPrivateKeyPwdLabel = new QLabel(this); + + //PEAP TTLS共有 + eapMethodLabel = new QLabel(this); + userNameLabel = new QLabel(this); + userPwdLabel = new QLabel(this); + userPwdFlagLabel = new QLabel(this); + + secuTypeCombox = new QComboBox(this); + pwdEdit = new LineEdit(this); + eapTypeCombox = new QComboBox(this); + //TLS + identityEdit = new LineEdit(this); + domainEdit = new LineEdit(this); + caCertPathCombox = new QComboBox(this); + caNeedBox = new QCheckBox(this); + clientCertPathCombox = new QComboBox(this); + clientPrivateKeyCombox = new QComboBox(this); + clientPrivateKeyPwdEdit = new LineEdit(this); + + //PEAP && TTLS + eapMethodCombox = new QComboBox(this); + userNameEdit = new LineEdit(this); + userPwdEdit = new LineEdit(this); + userPwdFlagBox = new QCheckBox(this); + + + mSecuLayout = new QFormLayout(this); + mSecuLayout->addRow(secuTypeLabel, secuTypeCombox); + mSecuLayout->addRow(pwdLabel, pwdEdit); + mSecuLayout->addRow(eapTypeLabel, eapTypeCombox); + mSecuLayout->addRow(identityLable, identityEdit); + mSecuLayout->addRow(domainLable, domainEdit); + mSecuLayout->addRow(caCertPathLabel, caCertPathCombox); + mSecuLayout->addRow(caNeedBox, caNeedFlagLabel); + mSecuLayout->addRow(clientCertPathLabel, clientCertPathCombox); + mSecuLayout->addRow(clientPrivateKeyLabel, clientPrivateKeyCombox); + mSecuLayout->addRow(clientPrivateKeyPwdLabel,clientPrivateKeyPwdEdit); + mSecuLayout->addRow(eapMethodLabel, eapMethodCombox); + mSecuLayout->addRow(userNameLabel, userNameEdit); + mSecuLayout->addRow(userPwdLabel, userPwdEdit); + mSecuLayout->addRow(userPwdFlagBox, userPwdFlagLabel); + + + secuTypeLabel->setText(tr("Security")); + pwdLabel->setText(tr("Password")); + //企业wifi共有 + eapTypeLabel->setText(tr("EAP type")); + //TLS + identityLable->setText(tr("Identity")); + domainLable->setText(tr("Domain")); + caCertPathLabel->setText(tr("CA certficate")); + caNeedFlagLabel->setText(tr("no need for CA certificate")); + clientCertPathLabel->setText(tr("User certificate")); + clientPrivateKeyLabel->setText(tr("User private key")); + clientPrivateKeyPwdLabel->setText(tr("User key password")); + + //PEAP TTLS共有 + eapMethodLabel->setText(tr("Ineer authentication")); + userNameLabel->setText(tr("Usename")); + userPwdLabel->setText(tr("Password")); + userPwdFlagLabel->setText(tr("Ask pwd each query")); + + secuTypeCombox->addItem(tr("None"),NONE); + secuTypeCombox->addItem(tr("WPA&WPA2 Personal"),WPA_AND_WPA2_PERSONAL); + secuTypeCombox->addItem(tr("WPA&WPA2 Enterprise"), WPA_AND_WPA2_ENTERPRISE); + secuTypeCombox->addItem(tr("WPA3 Personal"), WPA3_PERSONAL); + + eapTypeCombox->addItem("TLS", TLS); + eapTypeCombox->addItem("PEAP", PEAP); + eapTypeCombox->addItem("TTLS", TTLS); + eapTypeCombox->setCurrentIndex(TLS); + //TLS + caCertPathCombox->addItem(tr("None"), QString(tr("None"))); //无 + caCertPathCombox->addItem(tr("Choose from file..."), QString(tr("Choose from file..."))); //从文件中选择... + + clientCertPathCombox->addItem(tr("None"), QString(tr("None"))); //无 + clientCertPathCombox->addItem(tr("Choose from file..."), QString(tr("Choose from file..."))); //从文件中选择... + + clientPrivateKeyCombox->addItem(tr("None"), QString(tr("None"))); //无 + clientPrivateKeyCombox->addItem(tr("Choose from file..."), QString(tr("Choose from file..."))); //从文件中选择... + + pwdBox = new QCheckBox(this); + pwdBox->setStyleSheet("QCheckBox::indicator {width: 18px; height: 9px;}" + "QCheckBox::indicator:checked {image: url(:/res/h/show-pwd.png);}" + "QCheckBox::indicator:unchecked {image: url(:/res/h/hide-pwd.png);}"); + pwdBox->setCursor(Qt::PointingHandCursor); + pwdBox->setFixedSize(30, pwdEdit->height()); + //防止文本框输入内容位于按钮之下 + QMargins margins = pwdEdit->textMargins(); + pwdEdit->setTextMargins(margins.left(), margins.top(), pwdBox->width(), margins.bottom()); + QHBoxLayout *pPwdLayout = new QHBoxLayout(); + pPwdLayout->addStretch(); + pPwdLayout->addWidget(pwdBox); + pPwdLayout->setSpacing(0); + pPwdLayout->setContentsMargins(0, 0, 0, 0); + pwdEdit->setLayout(pPwdLayout); + pwdEdit->setEchoMode(QLineEdit::Password); + + userPwdBox = new QCheckBox(this); + userPwdBox->setStyleSheet("QCheckBox::indicator {width: 18px; height: 9px;}" + "QCheckBox::indicator:checked {image: url(:/res/h/show-pwd.png);}" + "QCheckBox::indicator:unchecked {image: url(:/res/h/hide-pwd.png);}"); + userPwdBox->setCursor(Qt::PointingHandCursor); + userPwdBox->setFixedSize(30, userPwdEdit->height()); + userPwdBox->setFocusPolicy(Qt::NoFocus); + //防止文本框输入内容位于按钮之下 + userPwdEdit->setTextMargins(margins.left(), margins.top(), userPwdBox->width(), margins.bottom()); + QHBoxLayout *puserPwdLayout = new QHBoxLayout(); + puserPwdLayout->addStretch(); + puserPwdLayout->addWidget(userPwdBox); + puserPwdLayout->setSpacing(0); + puserPwdLayout->setContentsMargins(0, 0, 0, 0); + userPwdEdit->setLayout(puserPwdLayout); + userPwdEdit->setEchoMode(QLineEdit::Password); + + privateKeyBox = new QCheckBox(this); + privateKeyBox->setStyleSheet("QCheckBox::indicator {width: 18px; height: 9px;}" + "QCheckBox::indicator:checked {image: url(:/res/h/show-pwd.png);}" + "QCheckBox::indicator:unchecked {image: url(:/res/h/hide-pwd.png);}"); + privateKeyBox->setCursor(Qt::PointingHandCursor); + privateKeyBox->setFixedSize(30, clientPrivateKeyPwdEdit->height()); + //防止文本框输入内容位于按钮之下 + clientPrivateKeyPwdEdit->setTextMargins(margins.left(), margins.top(), privateKeyBox->width(), margins.bottom()); + QHBoxLayout *pPrivateKeyPwdLayout = new QHBoxLayout(); + pPrivateKeyPwdLayout->addStretch(); + pPrivateKeyPwdLayout->addWidget(privateKeyBox); + pPrivateKeyPwdLayout->setSpacing(0); + pPrivateKeyPwdLayout->setContentsMargins(0, 0, 0, 0); + clientPrivateKeyPwdEdit->setLayout(pPrivateKeyPwdLayout); + clientPrivateKeyPwdEdit->setEchoMode(QLineEdit::Password); + + pwdEdit->setContextMenuPolicy(Qt::NoContextMenu); + clientPrivateKeyPwdEdit->setContextMenuPolicy(Qt::NoContextMenu); + userPwdEdit->setContextMenuPolicy(Qt::NoContextMenu); + + QRegExp rx("^[A-Za-z0-9`~!@#$%^&*()_-+=<>,.\\\/]+$"); + QRegExpValidator *latitude = new QRegExpValidator(rx, this); + pwdEdit->setValidator(latitude); + clientPrivateKeyPwdEdit->setValidator(latitude); + userPwdEdit->setValidator(latitude); + + showNone(); +} + +void SecurityPage::initConnect() +{ + //安全类型变化 +// connect(secuTypeCombox, &QComboBox::currentTextChanged, this, &SecurityPage::onSecuTypeComboxIndexChanged); + connect(secuTypeCombox, QOverload::of(&QComboBox::currentIndexChanged), this, &SecurityPage::onSecuTypeComboxIndexChanged); + //EAP方式变化 +// connect(eapTypeCombox, &QComboBox::currentTextChanged, this, &SecurityPage::onEapTypeComboxIndexChanged); + connect(eapTypeCombox, QOverload::of(&QComboBox::currentIndexChanged), this, &SecurityPage::onEapTypeComboxIndexChanged); + + connect(caNeedBox, &QCheckBox::clicked, this, &SecurityPage::onCaNeedBoxClicked); + + connect(pwdBox, &QCheckBox::clicked, this, &SecurityPage::onPwdBoxClicked); + connect(userPwdBox, &QCheckBox::clicked, this, &SecurityPage::onUserPwdBox); + connect(privateKeyBox, &QCheckBox::clicked, this, &SecurityPage::onPrivateKeyBoxClicked); + + connect(caCertPathCombox, static_cast(&QComboBox::currentIndexChanged), + this, &SecurityPage::onCaCertPathComboxIndexChanged); + + connect(clientCertPathCombox, static_cast(&QComboBox::currentIndexChanged), + this, &SecurityPage::onClientCertPathComboxIndexChanged); + + connect(clientPrivateKeyCombox, static_cast(&QComboBox::currentIndexChanged), + this, &SecurityPage::onClientPrivateKeyComboxIndexChanged); + + connect(secuTypeCombox, SIGNAL(currentIndexChanged(QString)), this, SLOT(setEnableOfSaveBtn())); + connect(pwdEdit, &LineEdit::textChanged, this, &SecurityPage::setEnableOfSaveBtn); + connect(eapTypeCombox, SIGNAL(currentIndexChanged(int)), this, SLOT(setEnableOfSaveBtn())); + connect(identityEdit, &LineEdit::textChanged, this, &SecurityPage::setEnableOfSaveBtn); + connect(caCertPathCombox, SIGNAL(currentTextChanged(QString)), this, SLOT(setEnableOfSaveBtn())); + connect(caNeedBox, &QCheckBox::stateChanged, this, &SecurityPage::setEnableOfSaveBtn); + connect(clientCertPathCombox, SIGNAL(currentTextChanged(QString)), this, SLOT(setEnableOfSaveBtn())); + connect(clientPrivateKeyCombox, SIGNAL(currentTextChanged(QString)), this, SLOT(setEnableOfSaveBtn())); + connect(clientPrivateKeyPwdEdit, &LineEdit::textChanged, this, &SecurityPage::setEnableOfSaveBtn); + connect(eapMethodCombox, SIGNAL(currentIndexChanged(int)), this, SLOT(setEnableOfSaveBtn())); + connect(userNameEdit, &LineEdit::textChanged, this, &SecurityPage::setEnableOfSaveBtn); + connect(userPwdEdit, &LineEdit::textChanged, this, &SecurityPage::setEnableOfSaveBtn); + +} + +void SecurityPage::setSecurity(KySecuType index) +{ + secuTypeCombox->setCurrentIndex(index); + onSecuTypeComboxIndexChanged(); +} + +void SecurityPage::setPsk(const QString &psk) +{ + pwdEdit->setText(psk); +} + +void SecurityPage::setTlsInfo(KyEapMethodTlsInfo &info) +{ + showTls(); + identityEdit->setText(info.identity); + domainEdit->setText(info.domain); + if (info.caCertPath.isEmpty()) { + caCertPathCombox->setItemText(0, QString(tr("None"))); + caNeedBox->setChecked(true); + caCertPathCombox->setEnabled(false); + } else { + caCertPathCombox->setItemText(0, info.caCertPath); + caNeedBox->setChecked(false); + caCertPathCombox->setEnabled(true); + } + + if (info.clientCertPath.isEmpty()) { + clientCertPathCombox->setItemText(0, ""); + } else { + clientCertPathCombox->setItemText(0, info.clientCertPath); + } + + if (info.clientPrivateKey.isEmpty()) { + clientPrivateKeyCombox->setItemText(0, ""); + } else { + clientPrivateKeyCombox->setItemText(0, info.clientPrivateKey); + } + + clientPrivateKeyPwdEdit->setText(info.clientPrivateKeyPWD); + +} + +void SecurityPage::setPeapInfo(KyEapMethodPeapInfo &info) +{ + showPeapOrTtls(); + eapTypeCombox->setCurrentIndex(PEAP); + onEapTypeComboxIndexChanged(); + if (info.phase2AuthMethod == KyAuthMethodMschapv2) { + eapMethodCombox->setCurrentIndex(MSCHAPV2_PEAP); + } else if (info.phase2AuthMethod == KyAuthMethodMd5){ + eapMethodCombox->setCurrentIndex(MD5_PEAP); + } else if (info.phase2AuthMethod == KyAuthMethodGtc) { + eapMethodCombox->setCurrentIndex(GTC_PEAP); + } + userNameEdit->setText(info.userName); + userPwdEdit->setText(info.userPWD); + if (info.m_passwdFlag) { + userPwdFlagBox->setChecked(true); + } else { + userPwdFlagBox->setChecked(false); + } +} + +void SecurityPage::setTtlsInfo(KyEapMethodTtlsInfo &info) +{ + showPeapOrTtls(); + eapTypeCombox->setCurrentIndex(TTLS); + onEapTypeComboxIndexChanged(); + + if (info.authType == AUTH_EAP) { + if (info.authEapMethod = KyAuthEapMethodMschapv2) { + eapMethodCombox->setCurrentIndex(MSCHAPV2_EAP); + } else if (info.authEapMethod = KyAuthEapMethodMd5) { + eapMethodCombox->setCurrentIndex(MD5_EAP); + } else if (info.authEapMethod = KyAuthEapMethodMd5) { + eapMethodCombox->setCurrentIndex(MD5_EAP); + } else { + qDebug() << "not support yet. AUTH_EAP method" << info.authEapMethod; + } + } else { + if (info.authNoEapMethod == KyAuthMethodPap) { + eapMethodCombox->setCurrentIndex(PAP); + } else if (info.authNoEapMethod == KyAuthMethodMschap) { + eapMethodCombox->setCurrentIndex(MSCHAP); + } else if (info.authNoEapMethod == KyAuthMethodMschapv2) { + eapMethodCombox->setCurrentIndex(MSCHAPV2); + } else if (info.authNoEapMethod == KyAuthMethodChap) { + eapMethodCombox->setCurrentIndex(CHAP); + } else { + qDebug() << "not support yet. AUTH_NO_EAP method" << info.authNoEapMethod; + } + } + userNameEdit->setText(info.userName); + userPwdEdit->setText(info.userPWD); + if (info.m_passwdFlag) { + userPwdFlagBox->setChecked(true); + } else { + userPwdFlagBox->setChecked(false); + } +} + +void SecurityPage::setSecurityVisible(const bool &visible) +{ + if (secuTypeLabel) { + secuTypeLabel->setVisible(visible); + } else { + qWarning() << "Set visible of secuTypeLabel failed because of null pointer" << Q_FUNC_INFO << __LINE__; + } + if (secuTypeCombox) { + secuTypeCombox->setVisible(visible); + } else { + qWarning() << "Set visible of secuTypeCombox failed because of null pointer" << Q_FUNC_INFO << __LINE__; + } +} + +void SecurityPage::updateTlsChange(KyEapMethodTlsInfo &info) +{ + KyEapMethodTlsInfo tlsInfo = assembleTlsInfo(); + if (tlsInfo.clientPrivateKeyPWD != info.clientPrivateKeyPWD) { + tlsInfo.bChanged = true; + } + tlsInfo.devIfaceName = info.devIfaceName; + info = tlsInfo; +} + +void SecurityPage::updatePeapChange(KyEapMethodPeapInfo &info) +{ + KyEapMethodPeapInfo peapInfo = assemblePeapInfo(); + if (peapInfo.userPWD != info.userPWD) { + peapInfo.bChanged = true; + } + info = peapInfo; +} + +void SecurityPage::updateTtlsChange(KyEapMethodTtlsInfo &info) +{ + KyEapMethodTtlsInfo ttlsInfo = assembleTtlsInfo(); + if (ttlsInfo.userPWD != info.userPWD) { + ttlsInfo.bChanged = true; + } + info = ttlsInfo; +} + +void SecurityPage::getSecuType(KySecuType &secuType, KyEapMethodType &enterpriseType) +{ + secuType = (KySecuType)secuTypeCombox->currentData().toInt(); + enterpriseType = (KyEapMethodType)eapTypeCombox->currentData().toInt(); +} + +bool SecurityPage::checkIsChanged(const ConInfo info) +{ + if (info.secType != secuTypeCombox->currentData().toInt()) { + return true; + } else { + if (info.secType == NONE) { + return false; + } else if (info.secType == WPA_AND_WPA2_PERSONAL || info.secType == WPA3_PERSONAL) { + return !(info.strPassword == pwdEdit->text()); + } else { + if (info.enterpriseType != eapTypeCombox->currentData().toInt()) { + return true; + } else { + if (info.enterpriseType == TLS) { + return !(info.tlsInfo == assembleTlsInfo()); + } else if (info.enterpriseType == PEAP) { + return !(info.peapInfo == assemblePeapInfo()); + } else if (info.enterpriseType == TTLS) { + return !(info.ttlsInfo == assembleTtlsInfo()); + } + } + } + } +} + +void SecurityPage::showNone() +{ + pwdEdit->hide(); + eapTypeCombox->hide(); + + identityEdit->hide(); + domainEdit->hide(); + caCertPathCombox->hide(); + caNeedBox->hide(); + clientCertPathCombox->hide(); + clientPrivateKeyCombox->hide(); + clientPrivateKeyPwdEdit->hide(); + + eapMethodCombox->hide(); + userNameEdit->hide(); + userPwdEdit->hide(); + userPwdFlagBox->hide(); + + pwdLabel->hide(); + //企业wifi共有 + eapTypeLabel->hide(); + //TLS + identityLable->hide(); + domainLable->hide(); + caCertPathLabel->hide(); + caNeedFlagLabel->hide(); + clientCertPathLabel->hide(); + clientPrivateKeyLabel->hide(); + clientPrivateKeyPwdLabel->hide(); + + //PEAP TTLS共有 + eapMethodLabel->hide(); + userNameLabel->hide(); + userPwdLabel->hide(); + userPwdFlagLabel->hide(); +} + +void SecurityPage::showPsk() +{ + pwdEdit->show(); + eapTypeCombox->hide(); + + identityEdit->hide(); + domainEdit->hide(); + caCertPathCombox->hide(); + caNeedBox->hide(); + clientCertPathCombox->hide(); + clientPrivateKeyCombox->hide(); + clientPrivateKeyPwdEdit->hide(); + + eapMethodCombox->hide(); + userNameEdit->hide(); + userPwdEdit->hide(); + userPwdFlagBox->hide(); + + pwdLabel->show(); + //企业wifi共有 + eapTypeLabel->hide(); + //TLS + identityLable->hide(); + domainLable->hide(); + caCertPathLabel->hide(); + caNeedFlagLabel->hide(); + clientCertPathLabel->hide(); + clientPrivateKeyLabel->hide(); + clientPrivateKeyPwdLabel->hide(); + + //PEAP TTLS共有 + eapMethodLabel->hide(); + userNameLabel->hide(); + userPwdLabel->hide(); + userPwdFlagLabel->hide(); +} + +void SecurityPage::showTls() +{ + pwdEdit->hide(); + eapTypeCombox->show(); + + identityEdit->show(); + domainEdit->show(); + caCertPathCombox->show(); + caNeedBox->show(); + clientCertPathCombox->show(); + clientPrivateKeyCombox->show(); + clientPrivateKeyPwdEdit->show(); + + eapMethodCombox->hide(); + userNameEdit->hide(); + userPwdEdit->hide(); + userPwdFlagBox->hide(); + + pwdLabel->hide(); + //企业wifi共有 + eapTypeLabel->show(); + //TLS + identityLable->show(); + domainLable->show(); + caCertPathLabel->show(); + caNeedFlagLabel->show(); + clientCertPathLabel->show(); + clientPrivateKeyLabel->show(); + clientPrivateKeyPwdLabel->show(); + + //PEAP TTLS共有 + eapMethodLabel->hide(); + userNameLabel->hide(); + userPwdLabel->hide(); + userPwdFlagLabel->hide(); +} + +void SecurityPage::showPeapOrTtls() +{ + pwdEdit->hide(); + eapTypeCombox->show(); + + identityEdit->hide(); + domainEdit->hide(); + caCertPathCombox->hide(); + caNeedBox->hide(); + clientCertPathCombox->hide(); + clientPrivateKeyCombox->hide(); + clientPrivateKeyPwdEdit->hide(); + + eapMethodCombox->show(); + userNameEdit->show(); + userPwdEdit->show(); + userPwdFlagBox->show(); + + pwdLabel->hide(); + //企业wifi共有 + eapTypeLabel->show(); + //TLS + identityLable->hide(); + domainLable->hide(); + caCertPathLabel->hide(); + caNeedFlagLabel->hide(); + clientCertPathLabel->hide(); + clientPrivateKeyLabel->hide(); + clientPrivateKeyPwdLabel->hide(); + + //PEAP TTLS共有 + eapMethodLabel->show(); + userNameLabel->show(); + userPwdLabel->show(); + userPwdFlagLabel->show(); +} + +KyEapMethodTlsInfo SecurityPage::assembleTlsInfo() +{ + KyEapMethodTlsInfo info; + info.identity = identityEdit->text(); + info.domain = domainEdit->text(); + info.caCertPath = caCertPathCombox->currentText(); + info.bNeedCa = !caNeedBox->isChecked(); + info.clientCertPath = clientCertPathCombox->currentText(); + info.clientPrivateKey = clientPrivateKeyCombox->currentText(); + info.clientPrivateKeyPWD = clientPrivateKeyPwdEdit->text(); + info.m_privateKeyPWDFlag = NetworkManager::Setting::None; + + return info; +} + +KyEapMethodPeapInfo SecurityPage::assemblePeapInfo() +{ + KyEapMethodPeapInfo info; +// info.phase2AuthMethod = (KyNoEapMethodAuth)eapMethodCombox->currentData().toInt(); + switch (eapMethodCombox->currentIndex()) { + case 0: + info.phase2AuthMethod = KyAuthMethodMschapv2; + break; + case 1: + info.phase2AuthMethod = KyAuthMethodMd5; + break; + case 2: + info.phase2AuthMethod = KyAuthMethodGtc; + break; + default: + break; + } + info.userName = userNameEdit->text(); + info.userPWD = userPwdEdit->text(); + info.m_passwdFlag = (userPwdFlagBox->isChecked() ? NetworkManager::Setting::NotSaved : NetworkManager::Setting::None); + + return info; +} +KyEapMethodTtlsInfo SecurityPage::assembleTtlsInfo() +{ + KyEapMethodTtlsInfo info; + switch (eapMethodCombox->currentIndex()) { + case PAP: + info.authType = AUTH_NO_EAP; + info.authNoEapMethod = KyAuthMethodPap; + break; + case MSCHAP: + info.authType = AUTH_NO_EAP; + info.authNoEapMethod = KyAuthMethodChap; + break; + case MSCHAPV2_EAP: + info.authType = AUTH_EAP; + info.authEapMethod = KyAuthEapMethodMschapv2; + break; + case MSCHAPV2: + info.authType = AUTH_NO_EAP; + info.authNoEapMethod = KyAuthMethodMschapv2; + break; + case CHAP: + info.authType = AUTH_NO_EAP; + info.authNoEapMethod = KyAuthMethodChap; + break; + case MD5_EAP: + info.authType = AUTH_EAP; + info.authEapMethod = KyAuthEapMethodMd5; + break; + case GTC_EAP: + info.authType = AUTH_EAP; + info.authEapMethod = KyAuthEapMethodGtc; + break; + default: + break; + } + info.userName = userNameEdit->text(); + info.userPWD = userPwdEdit->text(); + info.m_passwdFlag = (userPwdFlagBox->isChecked() ? NetworkManager::Setting::NotSaved : NetworkManager::Setting::None); + return info; +} + +void SecurityPage::updateSecurityChange(KyWirelessConnectSetting &setting) +{ + qDebug() << "secuTypeCombox->currentData()" << secuTypeCombox->currentData().toInt() << pwdEdit->text(); + if (secuTypeCombox->currentData().toInt() == NONE) { + setting.m_psk = ""; + } else { + setting.m_psk = pwdEdit->text(); + } + + if (secuTypeCombox->currentData().toInt() == NONE) { + setting.m_type = WpaNone; + } else if (secuTypeCombox->currentData().toInt() == WPA_AND_WPA2_PERSONAL) { + setting.m_type = WpaPsk; + } else if (secuTypeCombox->currentData().toInt() == WPA3_PERSONAL) { + setting.m_type = SAE; + } +} + +bool SecurityPage::checkConnectBtnIsEnabled() +{ + int index = secuTypeCombox->currentData().toInt(); + if (index == NONE) { + + } else if (index == WPA_AND_WPA2_PERSONAL || index == WPA3_PERSONAL) { + if (pwdEdit->text().isEmpty() || pwdEdit->text().length() < 8 ) { + qDebug() << "password is empty or length < 8"; + return false; + } + } else if (index == WPA_AND_WPA2_ENTERPRISE) { + int type = eapTypeCombox->currentData().toInt(); + if (type == TLS) { + if (identityEdit->text().isEmpty()) { + qDebug() << "tls identity is empty"; + return false; + } + QFile cafile(caCertPathCombox->currentText()); + if(!caNeedBox->isChecked() && !cafile.exists()) { + qDebug() << "ca cert filepath " << caCertPathCombox->currentText() << " is invalid"; + return false; + } + + QFile cliCafile(clientCertPathCombox->currentText()); + if(!cliCafile.exists()) { + qDebug() << "client cert filepath " << clientCertPathCombox->currentText() << " is invalid"; + return false; + } + + QFile cliKeyfile(clientPrivateKeyCombox->currentText()); + if(!cliKeyfile.exists()) { + qDebug() << "client private key filepath " << clientPrivateKeyCombox->currentText() << " is invalid"; + return false; + } + + if(clientPrivateKeyPwdEdit->text().isEmpty()) { + qDebug() << "client Private Key password is empty"; + return false; + } + } else if (type == PEAP || type == TTLS) { + if(userNameEdit->text().isEmpty() || userPwdEdit->text().isEmpty()) { + qDebug() << "user name or user password is empty"; + return false; + } + } + } + return true; +} + +void SecurityPage::setEnableOfSaveBtn() +{ + emit setSecuPageState(checkConnectBtnIsEnabled()); +} + +void SecurityPage::onSecuTypeComboxIndexChanged() +{ + int index = secuTypeCombox->currentData().toInt(); + if (index == WPA_AND_WPA2_PERSONAL || index == WPA3_PERSONAL) { + showPsk(); + } else if (index == WPA_AND_WPA2_ENTERPRISE) { + onEapTypeComboxIndexChanged(); + } else if (index == NONE) { + showNone(); + } +} + +void SecurityPage::onEapTypeComboxIndexChanged() +{ + qDebug() << "onEapTypeComboxIndexChanged"; + int index = eapTypeCombox->currentData().toInt(); + if (index == TLS) { + showTls(); + emit this->eapTypeChanged(TLS); + } else if (index == PEAP) { + showPeapOrTtls(); + eapMethodCombox->clear(); + eapMethodCombox->addItem("MSCHAPv2", MSCHAPV2_PEAP); + eapMethodCombox->addItem("MD5", MD5_PEAP); + eapMethodCombox->addItem("GTC", GTC_PEAP); + emit this->eapTypeChanged(PEAP); + } else if (index == TTLS) { + showPeapOrTtls(); + eapMethodCombox->clear(); + eapMethodCombox->addItem("pap", PAP); + eapMethodCombox->addItem("mschap", MSCHAP); + eapMethodCombox->addItem("mschapv2(eap)", MSCHAPV2_EAP); + eapMethodCombox->addItem("mschapv2", MSCHAPV2); + eapMethodCombox->addItem("chap", CHAP); + eapMethodCombox->addItem("md5(eap)", MD5_EAP); + eapMethodCombox->addItem("gtc(eap)", GTC_EAP); + emit this->eapTypeChanged(TTLS); + } +} + +void SecurityPage::onCaNeedBoxClicked() +{ + if (caNeedBox->isChecked()) { + caCertPathCombox->setItemText(0, QString(tr("None"))); + caCertPathCombox->setEnabled(false); + } else { + caCertPathCombox->setEnabled(true); + } +} + +void SecurityPage::onPwdBoxClicked() +{ + if (pwdEdit->echoMode() == QLineEdit::Password) { + pwdBox->setChecked(true); + pwdEdit->setEchoMode(QLineEdit::Normal); + } else { + pwdBox->setChecked(false); + pwdEdit->setEchoMode(QLineEdit::Password); + } +} + +void SecurityPage::onUserPwdBox() +{ + if (userPwdEdit->echoMode() == QLineEdit::Password) { + userPwdBox->setChecked(true); + userPwdEdit->setEchoMode(QLineEdit::Normal); + } else { + userPwdBox->setChecked(false); + userPwdEdit->setEchoMode(QLineEdit::Password); + } + +} + +void SecurityPage::onPrivateKeyBoxClicked() +{ + if (clientPrivateKeyPwdEdit->echoMode() == QLineEdit::Password) { + privateKeyBox->setChecked(true); + clientPrivateKeyPwdEdit->setEchoMode(QLineEdit::Normal); + } else { + privateKeyBox->setChecked(false); + clientPrivateKeyPwdEdit->setEchoMode(QLineEdit::Password); + } +} + +void SecurityPage::onCaCertPathComboxIndexChanged(QString str) +{ + if (str.contains("Choose from file...") || str.contains("从文件选择...")) + { + QString fileName = QFileDialog::getOpenFileName(this, tr("Choose a CA certificate"), "recent:///", + tr("CA Files (*.pem *.der *.p12 *.crt *.cer *.pfx)")); + if (!fileName.isNull()) { + QStringList nameList = fileName.split("/"); + caCertPathCombox->blockSignals(true); + caCertPathCombox->setItemText(0, fileName); + caCertPathCombox->setCurrentIndex(0); + caCertPathCombox->blockSignals(false); + } else { + caCertPathCombox->blockSignals(true); + caCertPathCombox->setItemText(0, tr("None")); + caCertPathCombox->setCurrentIndex(0); + caCertPathCombox->blockSignals(false); + } + } else { + qWarning() << "Choose file is null or unvalible"; + } +} + +void SecurityPage::onClientCertPathComboxIndexChanged(QString str) +{ + if (str.contains("Choose from file...") || str.contains("从文件选择...")) + { + QString fileName = QFileDialog::getOpenFileName(this, tr("Choose a CA certificate"), "recent:///", + tr("CA Files (*.pem *.der *.p12 *.crt *.cer *.pfx)")); + if (!fileName.isNull()) { + clientCertPathCombox->blockSignals(true); + clientCertPathCombox->setItemText(0, fileName); + clientCertPathCombox->setCurrentIndex(0); + clientCertPathCombox->blockSignals(false); + } else { + clientCertPathCombox->blockSignals(true); + clientCertPathCombox->setItemText(0, tr("None")); + clientCertPathCombox->setCurrentIndex(0); + clientCertPathCombox->blockSignals(false); + } + } else { + qWarning() << "Choose file is null or unvalible"; + } +} + +void SecurityPage::onClientPrivateKeyComboxIndexChanged(QString str) +{ + if (str.contains("Choose from file...") || str.contains("从文件选择...")) + { + QString fileName = QFileDialog::getOpenFileName(this, tr("Choose a CA certificate"), "recent:///", + tr("CA Files (*.pem *.der *.p12 *.crt *.cer *.pfx)")); + if (!fileName.isNull()) { + QStringList nameList = fileName.split("/"); + clientPrivateKeyCombox->blockSignals(true); + clientPrivateKeyCombox->setItemText(0, fileName); + clientPrivateKeyCombox->setCurrentIndex(0); + clientPrivateKeyCombox->blockSignals(false); + } else { + clientPrivateKeyCombox->blockSignals(true); + clientPrivateKeyCombox->setItemText(0, tr("None")); + clientPrivateKeyCombox->setCurrentIndex(0); + clientPrivateKeyCombox->blockSignals(false); + } + } else { + qWarning() << "Choose file is null or unvalible"; + } +} diff --git a/src/frontend/netdetails/securitypage.h b/src/frontend/netdetails/securitypage.h new file mode 100644 index 00000000..462b920d --- /dev/null +++ b/src/frontend/netdetails/securitypage.h @@ -0,0 +1,113 @@ +#ifndef SECURITYWIDGET_H +#define SECURITYWIDGET_H + +#include +#include +#include +#include +#include +#include + +#include "coninfo.h" + +class SecurityPage : public QFrame +{ + Q_OBJECT +public: + SecurityPage(QWidget *parent = nullptr); + + void setSecurity(KySecuType index); + void setPsk(const QString &psk); + void setTlsInfo(KyEapMethodTlsInfo &info); + void setPeapInfo(KyEapMethodPeapInfo &info); + void setTtlsInfo(KyEapMethodTtlsInfo &info); + void setSecurityVisible(const bool &visible); + + bool checkIsChanged(const ConInfo info); + void updateSecurityChange(KyWirelessConnectSetting &setting); + void updateTlsChange(KyEapMethodTlsInfo &info); + void updatePeapChange(KyEapMethodPeapInfo &info); + void updateTtlsChange(KyEapMethodTtlsInfo &info); + + void getSecuType(KySecuType &secuType, KyEapMethodType &enterpriseType); + +private: + QFormLayout *mSecuLayout; + +private: + + QLabel *secuTypeLabel; + QLabel *pwdLabel; + //企业wifi共有 + QLabel *eapTypeLabel; + //TLS + QLabel *identityLable; + QLabel *domainLable; + QLabel *caCertPathLabel; + QLabel *caNeedFlagLabel; + QLabel *clientCertPathLabel; + QLabel *clientPrivateKeyLabel; + QLabel *clientPrivateKeyPwdLabel; + + //PEAP TTLS共有 + QLabel *eapMethodLabel; + QLabel *userNameLabel; + QLabel *userPwdLabel; + QLabel *userPwdFlagLabel; + + QComboBox *secuTypeCombox; + LineEdit *pwdEdit; + QComboBox *eapTypeCombox; + //TLS + LineEdit *identityEdit; + LineEdit *domainEdit; + QComboBox *caCertPathCombox; + QCheckBox *caNeedBox; + QComboBox *clientCertPathCombox; + QComboBox *clientPrivateKeyCombox; + LineEdit *clientPrivateKeyPwdEdit; + + //PEAP && TTLS + QComboBox *eapMethodCombox; + LineEdit *userNameEdit; + LineEdit *userPwdEdit; + QCheckBox *userPwdFlagBox; + + QCheckBox *pwdBox; + QCheckBox *userPwdBox; + QCheckBox *privateKeyBox; + + void showNone(); + void showPsk(); + void showTls(); + void showPeapOrTtls(); + void initUI(); + void initConnect(); + + KyEapMethodTlsInfo assembleTlsInfo(); + KyEapMethodPeapInfo assemblePeapInfo(); + KyEapMethodTtlsInfo assembleTtlsInfo(); + + bool checkConnectBtnIsEnabled(); + + +private slots: + void onSecuTypeComboxIndexChanged(); + void onEapTypeComboxIndexChanged(); + void setEnableOfSaveBtn(); + + void onCaNeedBoxClicked(); + void onPwdBoxClicked(); + void onUserPwdBox(); + void onPrivateKeyBoxClicked(); + + void onCaCertPathComboxIndexChanged(QString str); + void onClientCertPathComboxIndexChanged(QString str); + void onClientPrivateKeyComboxIndexChanged(QString str); + +signals: + void setSecuPageState(bool); + void eapTypeChanged(const KyEapMethodType &type); +}; + +#endif // SECURITYWIDGET_H diff --git a/src/frontend/tab-pages/lanpage.cpp b/src/frontend/tab-pages/lanpage.cpp new file mode 100644 index 00000000..27799a92 --- /dev/null +++ b/src/frontend/tab-pages/lanpage.cpp @@ -0,0 +1,1257 @@ +#include "lanpage.h" +#include +#include + +#define MAIN_LAYOUT_MARGINS 0,0,0,0 +#define MAIN_LAYOUT_SPACING 0 +#define TITLE_FRAME_HEIGHT 52 +#define TITLE_LAYOUT_MARGINS 24,0,24,0 +#define LAN_LIST_SPACING 0 +#define TEXT_MARGINS 16,0,0,0 +#define SETTINGS_LAYOUT_MARGINS 24,16,24,16 +#define TRANSPARENT_COLOR QColor(0,0,0,0) +#define ITEM_HEIGHT 48 + +#define LOG_FLAG "[LanPage]" + +const QString EMPTY_CONNECT_UUID = "emptyconnect"; + +const QString WIRED_SWITCH = "wiredswitch"; + +LanPage::LanPage(QWidget *parent) : TabPage(parent) +{ + m_activeResourse = new KyActiveConnectResourse(this); + m_connectResourse = new KyConnectResourse(this); + m_deviceResource = new KyNetworkDeviceResourse(this); + m_wiredConnectOperation = new KyWiredConnectOperation(this); + + initUI(); + initLanDevice(); + initNetSwitch(); + initLanDeviceState(); + + initDeviceCombox(); + initLanArea(); + + connect(m_activeResourse, &KyActiveConnectResourse::stateChangeReason, this, &LanPage::onConnectionStateChange); + connect(m_activeResourse, &KyActiveConnectResourse::activeConnectRemove, this, [=] (QString activeConnectUuid) { + sendLanStateChangeSignal(activeConnectUuid,Deactivated); + } ); + + connect(m_connectResourse, &KyConnectResourse::connectionAdd, this, &LanPage::onAddConnection); + connect(m_connectResourse, &KyConnectResourse::connectionRemove, this, &LanPage::onRemoveConnection); + connect(m_connectResourse, &KyConnectResourse::connectionUpdate, this, &LanPage::onUpdateConnection); + + connect(m_deviceResource, &KyNetworkDeviceResourse::deviceAdd, this, &LanPage::onDeviceAdd); + connect(m_deviceResource, &KyNetworkDeviceResourse::deviceRemove, this, &LanPage::onDeviceRemove); + connect(m_deviceResource, &KyNetworkDeviceResourse::deviceNameUpdate, this, &LanPage::onDeviceNameUpdate); + + connect(m_deviceResource, &KyNetworkDeviceResourse::carrierChanage, this, &LanPage::onDeviceCarriered); + connect(m_deviceResource, &KyNetworkDeviceResourse::deviceActiveChanage, this, &LanPage::onDeviceActiveChanage); + + connect(m_wiredConnectOperation, &KyWiredConnectOperation::activateConnectionError, this, &LanPage::activateFailed); + connect(m_wiredConnectOperation, &KyWiredConnectOperation::deactivateConnectionError, this, &LanPage::deactivateFailed); + +} + +LanPage::~LanPage() +{ + +} + +void LanPage::initLanDevice() +{ + m_devList.clear(); + m_deviceResource->getNetworkDeviceList(NetworkManager::Device::Type::Ethernet, m_devList); + + m_currentDeviceName = getDefaultDeviceName(WIRED); + bool getDefault = !m_currentDeviceName.isEmpty(); + if (getDefault) { + if (m_deviceResource->wiredDeviceIsCarriered(m_currentDeviceName)) { + return; + } + } + + QList activedList; + for (int index = 0; index < m_devList.size(); ++index) { + m_activeResourse->getActiveConnectionList(m_devList.at(index), + NetworkManager::ConnectionSettings::Wired, activedList); + if (!activedList.isEmpty()) { + m_currentDeviceName = m_devList.at(index); + if (!getDefault) { + setDefaultDevice(WIRED, m_currentDeviceName); + } + return; + } + } + + for (int index = 0; index < m_devList.size(); ++index) { + if (m_deviceResource->wiredDeviceIsCarriered(m_devList.at(index))) { + m_currentDeviceName = m_devList.at(index); + if (!getDefault) { + setDefaultDevice(WIRED, m_currentDeviceName); + } + return; + } + } + return; +} + +void LanPage::initLanDeviceState() +{ + QMap deviceStateMap; + getDeviceEnableState(WIRED, deviceStateMap); + + QStringList disableDeviceList; + disableDeviceList.clear(); + m_enableDeviceList.clear(); + for (int index = 0; index < m_devList.count(); ++index) { + QString deviceName = m_devList.at(index); + if (deviceStateMap.contains(deviceName)) { + if (deviceStateMap[deviceName]) { + m_enableDeviceList<keys().contains(WIRED_SWITCH)) { + m_wiredSwitch = m_switchGsettings->get(WIRED_SWITCH).toBool(); + connect(m_switchGsettings, &QGSettings::changed, this, &LanPage::onSwithGsettingsChanged); + } + } else { + qDebug()<<"[LanPage] org.ukui.kylin-nm.switch is not installed!"; + } + + if (m_devList.count() == 0) { + qDebug() << "[wiredSwitch]:init not enable when no device"; + m_wiredSwitch = false; + m_netSwitch->setSwitchStatus(m_wiredSwitch); + m_netSwitch->setEnabled(false); + } + + qDebug() << "[wiredSwitch]:init state:" << m_wiredSwitch; + + m_netSwitch->setSwitchStatus(m_wiredSwitch); + + connect(m_netSwitch, &SwitchButton::clicked, this, &LanPage::onLanSwitchClicked); + + return; +} + +void LanPage::onSwithGsettingsChanged(const QString &key) +{ + if (key == WIRED_SWITCH) { + m_netSwitch->blockSignals(true); + + m_wiredSwitch = m_switchGsettings->get(WIRED_SWITCH).toBool(); + qDebug()<<"[LanPage] SwitchButton statue changed to:" << m_wiredSwitch; + + KyWiredConnectOperation wiredOperation; + if (m_wiredSwitch) { + for (int index = 0; index < m_enableDeviceList.size(); ++index) { + qDebug()<<"[LanPage] open wired device "<< m_enableDeviceList.at(index); + wiredOperation.openWiredNetworkWithDevice(m_enableDeviceList.at(index)); + } + } else { + for (int index = 0; index < m_enableDeviceList.size(); ++index) { + qDebug()<<"[LanPage] close wired device "<< m_enableDeviceList.at(index); + wiredOperation.closeWiredNetworkWithDevice(m_enableDeviceList.at(index)); + } + } + + initDeviceCombox(); + initLanArea(); + + m_netSwitch->setSwitchStatus(m_wiredSwitch); + + m_netSwitch->blockSignals(false); + } +} + +void LanPage::onLanSwitchClicked() +{ + qDebug()<<"[LanPage] On lan switch button clicked! Status:" <getSwitchStatus() + <<"devices count:"<showDesktopNotify(tr("No ethernet device avaliable")); + } else { + if (m_netSwitch->getSwitchStatus()) { + //qDebug() << "[wiredSwitch]set true after clicked"; + m_switchGsettings->set(WIRED_SWITCH, true); + } else { + //qDebug() << "[wiredSwitch]set false after clicked"; + m_switchGsettings->set(WIRED_SWITCH,false); + } + } +} + +void LanPage::getEnabledDevice(QStringList &enableDeviceList) +{ + int index = 0; + QMap deviceMap; + + if (m_devList.isEmpty()) { + qDebug()<<"[LanPage] there is not wired device."; + return; + } + + getDeviceEnableState(WIRED, deviceMap); + for (index = 0; index < m_devList.size(); ++index) { + if (deviceMap.contains(m_devList.at(index))) { + if (deviceMap[m_devList.at(index)]) { + enableDeviceList << m_devList.at(index); + } + } else { + saveDeviceEnableState(m_devList.at(index), true); + enableDeviceList << m_devList.at(index); + } + } + + return; +} + +void LanPage::getDisabledDevices(QStringList &disableDeviceList) +{ + int index = 0; + QMap deviceMap; + + if (m_devList.isEmpty()) { + qDebug()<<"[LanPage] there is not wired device."; + return; + } + + getDeviceEnableState(WIRED, deviceMap); + for (index = 0; index < m_devList.size(); ++index) { + if (deviceMap.contains(m_devList.at(index))) { + if (!deviceMap[m_devList.at(index)]) { + disableDeviceList << m_devList.at(index); + } + } + } + + return; +} + +void LanPage::initDeviceCombox() +{ + //TODO 获取设备列表,单设备时隐藏下拉框,多设备时添加到下拉框;m_devList记录插入的所有设备,deviceMap记录设备状态 + disconnect(m_deviceComboBox, QOverload::of(&QComboBox::currentIndexChanged), + this, &LanPage::onDeviceComboxIndexChanged); + + m_deviceComboBox->clear(); + + if (m_wiredSwitch) { + int enableDeviceCount = m_enableDeviceList.count(); + if (enableDeviceCount > 1) { + for (int index = 0; index < enableDeviceCount; ++index) { + m_deviceComboBox->addItem(m_enableDeviceList.at(index)); + } + + m_deviceFrame->show(); + m_tipsLabel->hide(); + m_deviceComboBox->show(); + + if (m_currentDeviceName != m_deviceComboBox->currentText()) { + if (m_enableDeviceList.contains(m_currentDeviceName)) { + m_deviceComboBox->setCurrentText(m_currentDeviceName); + } else { + m_currentDeviceName = m_deviceComboBox->currentText(); + } + } + + } else if (enableDeviceCount == 1) { + m_deviceFrame->hide(); + + if (m_currentDeviceName != m_enableDeviceList.at(0)) { + m_currentDeviceName = m_enableDeviceList.at(0); + } + } else { + m_deviceFrame->show(); + m_deviceComboBox->hide(); + m_tipsLabel->show(); + m_currentDeviceName = ""; + } + } else { + m_deviceFrame->hide(); + m_currentDeviceName = ""; + + } + + setDefaultDevice(WIRED, m_currentDeviceName); + connect(m_deviceComboBox, QOverload::of(&QComboBox::currentIndexChanged), + this, &LanPage::onDeviceComboxIndexChanged); + return; +} + +void LanPage::addEmptyConnectItem(QMap &connectMap, + QListWidget *lanListWidget) +{ + QListWidgetItem *p_listWidgetItem = addNewItem(nullptr, lanListWidget); + connectMap.insert(EMPTY_CONNECT_UUID, p_listWidgetItem); + + return; +} + + +void LanPage::deleteConnectionMapItem(QMap &connectMap, + QListWidget *lanListWidget, QString uuid) +{ + QListWidgetItem *p_listWidgetItem = connectMap.value(uuid); + if (p_listWidgetItem) { + connectMap.remove(uuid); + LanListItem *p_lanItem = (LanListItem *)lanListWidget->itemWidget(p_listWidgetItem); + lanListWidget->removeItemWidget(p_listWidgetItem); + + delete p_lanItem; + p_lanItem = nullptr; + + delete p_listWidgetItem; + p_listWidgetItem = nullptr; + } + + return; +} + +void LanPage::clearConnectionMap(QMap &connectMap, + QListWidget *lanListWidget) +{ + QMap::iterator iter; + + iter = connectMap.begin(); + while (iter != connectMap.end()) { + qDebug()<<"[LanPage] clear connection map item"<< iter.key(); + + QListWidgetItem *p_widgetItem = iter.value(); + LanListItem *p_lanItem = (LanListItem *)lanListWidget->itemWidget(p_widgetItem); + lanListWidget->removeItemWidget(p_widgetItem); + + delete p_lanItem; + p_lanItem = nullptr; + + delete p_widgetItem; + p_widgetItem = nullptr; + + iter = connectMap.erase(iter); + } + + return; +} + +void LanPage::constructActiveConnectionArea() +{ + QList activedList; + + activedList.clear(); + clearConnectionMap(m_activeConnectionMap, m_activatedLanListWidget); + + m_activeResourse->getActiveConnectionList(m_currentDeviceName, + NetworkManager::ConnectionSettings::Wired, activedList); //激活列表的显示 + qDebug() << "[LanPage] construct active connection area get Active list size:" << activedList.size(); + if (!activedList.isEmpty()) { + for (int index = 0; index < activedList.size(); index++) { + KyConnectItem *p_activeConnectionItem = activedList.at(index); + qDebug() << "[LanPage] construct active connection area. add active item" + << p_activeConnectionItem->m_connectName; + QListWidgetItem *p_listWidgetItem = addNewItem(p_activeConnectionItem, m_activatedLanListWidget); + m_activeConnectionMap.insert(p_activeConnectionItem->m_connectUuid, p_listWidgetItem); + + delete p_activeConnectionItem; + p_activeConnectionItem = nullptr; + } + } else { + qDebug()<<"[LanPage] there is not active"; + addEmptyConnectItem(m_activeConnectionMap, m_activatedLanListWidget); + } + + return; +} + +void LanPage::constructConnectionArea() +{ + QList deactivedList; + + deactivedList.clear(); + clearConnectionMap(m_inactiveConnectionMap, m_inactivatedLanListWidget); + + m_connectResourse->getConnectionList(m_currentDeviceName, NetworkManager::ConnectionSettings::Wired, deactivedList); //未激活列表的显示 + qDebug() << "[LanPage]construct connection area get connection list size:" << deactivedList.size(); + if (!deactivedList.isEmpty()) { + for (int index = 0; index < deactivedList.size(); index++) { + KyConnectItem *p_deactiveConnectionItem = deactivedList.at(index); + qDebug()<<"[LanPage] construct connection area add deactive item"<m_connectName; + QListWidgetItem *p_listWidgetItem = addNewItem(p_deactiveConnectionItem, m_inactivatedLanListWidget); + if (m_inactiveConnectionMap.contains(p_deactiveConnectionItem->m_connectUuid)) { + qDebug()<m_connectUuid; + } + m_inactiveConnectionMap.insert(p_deactiveConnectionItem->m_connectUuid, p_listWidgetItem); + + delete p_deactiveConnectionItem; + p_deactiveConnectionItem = nullptr; + + } + } + if (m_inactivatedLanListWidget->count() < MAX_ITEMS) { + m_inactivatedLanListWidget->setFixedWidth(MIN_WIDTH); + } else { + m_inactivatedLanListWidget->setFixedWidth(MAX_WIDTH); + } + return; +} + +void LanPage::initLanArea() +{ + if (!m_wiredSwitch || m_currentDeviceName.isEmpty()) { + m_activatedNetDivider->hide(); + m_activatedNetFrame->hide(); + + m_inactivatedNetFrame->hide(); + } else { + m_activatedNetDivider->show(); + m_activatedNetFrame->show(); + constructActiveConnectionArea(); + + m_inactivatedNetFrame->show(); + constructConnectionArea(); + } + + return; +} + +bool LanPage::removeConnectionItem(QMap &connectMap, + QListWidget *lanListWidget, QString path) +{ + QMap::iterator iter; + for (iter = connectMap.begin(); iter != connectMap.end(); ++iter) { + QListWidgetItem *p_listWidgetItem = iter.value(); + LanListItem *p_lanItem = (LanListItem*)lanListWidget->itemWidget(p_listWidgetItem); + if (p_lanItem->getConnectionPath() == path) { + qDebug()<<"[LanPage] Remove a connection from list"; + + lanListWidget->removeItemWidget(p_listWidgetItem); + + delete p_lanItem; + p_lanItem = nullptr; + + delete p_listWidgetItem; + p_listWidgetItem = nullptr; + + iter = connectMap.erase(iter); + if (m_inactivatedLanListWidget->count() < MAX_ITEMS) { + m_inactivatedLanListWidget->setFixedWidth(MIN_WIDTH); + } + return true; + } + } + + return false; +} + +void LanPage::onRemoveConnection(QString path) //删除时后端会自动断开激活,将其从未激活列表中删除 +{ + //for dbus + qDebug() << "[LanPage] emit lanRemove because onRemoveConnection " << path; + emit lanRemove(path); + + if (removeConnectionItem(m_inactiveConnectionMap, m_inactivatedLanListWidget, path)) { + return; + } else { + removeConnectionItem(m_activeConnectionMap, m_activatedLanListWidget, path); + if (m_activeConnectionMap.count() <= 0) { + addEmptyConnectItem(m_activeConnectionMap, m_activatedLanListWidget); + } + + return; + } +} + +void LanPage::onAddConnection(QString uuid) //新增一个有线连接,将其加入到激活列表 +{ + if (!m_connectResourse->isWiredConnection(uuid)) { + return; + } + + KyConnectItem *p_newItem = nullptr; + p_newItem = m_connectResourse->getConnectionItemByUuid(uuid); + if (nullptr == p_newItem) { + return; + } + + sendLanAddSignal(p_newItem); + + if (p_newItem->m_ifaceName == m_currentDeviceName || p_newItem->m_ifaceName == "") { + qDebug()<<"[LanPage] Add a new connection, name:"<m_connectName; + QListWidgetItem *p_listWidgetItem = insertNewItem(p_newItem, m_inactivatedLanListWidget); + if (m_inactiveConnectionMap.contains(p_newItem->m_connectUuid)) { + qDebug()<m_connectUuid; + } + m_inactiveConnectionMap.insert(p_newItem->m_connectUuid, p_listWidgetItem); + } + + delete p_newItem; + p_newItem = nullptr; + if (m_inactivatedLanListWidget->count() >= MAX_ITEMS) { + m_inactivatedLanListWidget->setFixedWidth(MAX_WIDTH); + } + return; +} + +void LanPage::addDeviceForCombox(QString deviceName) +{ + disconnect(m_deviceComboBox, QOverload::of(&QComboBox::currentIndexChanged), + this, &LanPage::onDeviceComboxIndexChanged); + + if (m_wiredSwitch) { + if (1 == m_enableDeviceList.count()) { + //1、从无到有添加第一块有线网卡 + //2、有多快网卡,但是没有使能 + m_deviceFrame->hide(); + m_currentDeviceName = deviceName; + setDefaultDevice(WIRED, m_currentDeviceName); + } else if (2 == m_enableDeviceList.count()) { + //3、现在有且只有一块网卡,并已使能 + //4、有多快网卡,且使能了其中一块 + m_deviceComboBox->addItem(m_currentDeviceName); + m_deviceComboBox->addItem(deviceName); + + m_deviceFrame->show(); + m_tipsLabel->hide(); + m_deviceComboBox->show(); + } else if (m_enableDeviceList.count() > 2) { + //5、有多快网卡且使能了多块网卡 + m_deviceComboBox->addItem(deviceName); + } + } + + connect(m_deviceComboBox, QOverload::of(&QComboBox::currentIndexChanged), + this, &LanPage::onDeviceComboxIndexChanged); + return; +} + +void LanPage::onDeviceAdd(QString deviceName, NetworkManager::Device::Type deviceType) +{ + if (!m_deviceResource->deviceIsWired(deviceName)) { + return; + } + + if (m_devList.contains(deviceName)) { + return; + } + + if (m_devList.count() == 0) {// 有线网卡从无到有,打开开关 + m_netSwitch->setEnabled(true); + m_wiredSwitch = m_switchGsettings->get(WIRED_SWITCH).toBool(); + m_netSwitch->setSwitchStatus(m_wiredSwitch); + } + + qDebug() << "[LanPage] Begin add device:" << deviceName; + + m_devList << deviceName; + saveDeviceEnableState(deviceName, true); + m_enableDeviceList<::of(&QComboBox::currentIndexChanged), + this, &LanPage::onDeviceComboxIndexChanged); + + if (m_wiredSwitch) { + if (0 == m_enableDeviceList.count()) { + //1、没有使能任何网卡 + goto l_out; + } else if (1 == m_enableDeviceList.count()) { + //2、使能了一个网卡,且当前网卡是要删除的网卡 + if (m_currentDeviceName == deviceName) { + m_deviceFrame->show(); + m_deviceComboBox->hide(); + m_tipsLabel->show(); + m_currentDeviceName = ""; + setDefaultDevice(WIRED, m_currentDeviceName); + } + } else if (2 == m_enableDeviceList.count()) { + //3、使能了两个网卡,且包括要删除的网卡,有可能是要删除的网卡 + if (m_deviceComboBox->findText(deviceName) != -1) { + for (int index = m_deviceComboBox->count() - 1; index >= 0; index--) { + if (m_currentDeviceName == deviceName + && m_deviceComboBox->itemText(index) != deviceName) { + m_currentDeviceName = m_deviceComboBox->itemText(index); + setDefaultDevice(WIRED, m_currentDeviceName); + } + m_deviceComboBox->removeItem(index); + } + + m_tipsLabel->hide(); + m_deviceFrame->hide(); + m_deviceComboBox->hide(); + } + } else { + //4、使能了多个网卡,且包括要删除的网卡,有可能是正要删除的网卡 + int index = m_deviceComboBox->findText(deviceName); + if (index != -1) { + m_deviceComboBox->removeItem(index); + if (m_currentDeviceName == deviceName) { + m_currentDeviceName = m_deviceComboBox->currentText(); + setDefaultDevice(WIRED, m_currentDeviceName); + } + } + } + } + +l_out: + connect(m_deviceComboBox, QOverload::of(&QComboBox::currentIndexChanged), + this, &LanPage::onDeviceComboxIndexChanged); + + return; +} + +void LanPage::onDeviceRemove(QString deviceName) +{ + if (!m_devList.contains(deviceName)) { + return; + } + + qDebug() << "[LanPage] deviceRemove:" << deviceName; + + m_devList.removeOne(deviceName); + if (m_devList.count() == 0) { + m_wiredSwitch = false; + m_netSwitch->setSwitchStatus(m_wiredSwitch); + m_netSwitch->setEnabled(false); + qDebug() << "[wiredSwitch]set not enable after device remove"; + } + + QString nowDevice = m_currentDeviceName; + deleteDeviceFromCombox(deviceName); + if (nowDevice == deviceName) { + setDefaultDevice(WIRED, m_currentDeviceName); + initLanArea(); + } + + if (m_enableDeviceList.contains(deviceName)) { + m_enableDeviceList.removeOne(deviceName); + } + deleteDeviceEnableState(deviceName); + + emit deviceStatusChanged(); + + return; +} + +void LanPage::updateDeviceCombox(QString oldDeviceName, QString newDeviceName) +{ + if (m_currentDeviceName == oldDeviceName) { + m_currentDeviceName = newDeviceName; + setDefaultDevice(WIRED, m_currentDeviceName); + } + + int index = m_deviceComboBox->findText(oldDeviceName); + if (index != -1) { + m_deviceComboBox->setItemText(index, newDeviceName); + } + + return; +} + +void LanPage::onDeviceNameUpdate(QString oldName, QString newName) +{ + if (m_devList.contains(oldName)) { + m_devList.removeOne(oldName); + m_devList.append(newName); + + if (m_enableDeviceList.contains(oldName)) { + m_enableDeviceList.removeOne(oldName); + m_enableDeviceList.append(newName); + } + qDebug() << "[LanPage] emit deviceNameUpdate " << oldName << newName; + + updateDeviceCombox(oldName, newName); + if (m_currentDeviceName == newName) { + initLanArea(); + } + + emit deviceNameChanged(oldName, newName, WIRED); + } +} + +void LanPage::onDeviceCarriered(QString deviceName, bool pluged) +{ + if (!pluged) { + return; + } + if (m_enableDeviceList.contains(deviceName)) { + m_wiredConnectOperation->openWiredNetworkWithDevice(deviceName); + updateCurrentDevice(deviceName); + } + return; +} + +void LanPage::onDeviceActiveChanage(QString deviceName, bool deviceActive) +{ + if (!m_devList.contains(deviceName)) { + return; + } + + if (deviceActive) { + if (!m_wiredSwitch || !m_enableDeviceList.contains(deviceName)) { + qDebug()<< LOG_FLAG << "close disabled device"; + m_wiredConnectOperation->closeWiredNetworkWithDevice(deviceName); + } + } + + return; +} + + +void LanPage::onDeviceComboxIndexChanged(int currentIndex) +{ + //TODO 设备变更时更新设备和列表 + m_currentDeviceName = m_deviceComboBox->currentText(); + qDebug() << "[LanPage]Current Device Changed to:" << m_currentDeviceName; + initLanArea(); +} + +void LanPage::onShowControlCenter() +{ + QProcess process; + process.startDetached("ukui-control-center -m netconnect"); +} + +void LanPage::initUI() +{ + m_titleLabel->setText(tr("LAN")); + + m_activatedNetLabel->setText(tr("Activated LAN")); + m_activatedLanListWidget = new QListWidget(m_activatedNetFrame); + m_activatedLanListWidget->setFrameShape(QFrame::Shape::NoFrame); + m_activatedLanListWidget->setSpacing(LAN_LIST_SPACING); + m_activatedLanListWidget->setFixedHeight(ITEM_HEIGHT); //active区域固定高度,只显示一个条目 + m_activatedLanListWidget->setFixedWidth(MIN_WIDTH); + m_activatedLanListWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_activatedNetLayout->addWidget(m_activatedLanListWidget); + + m_inactivatedNetLabel->setText(tr("Inactivated LAN")); + m_inactivatedLanListWidget = new QListWidget(m_inactivatedNetListArea); + m_inactivatedLanListWidget->setFrameShape(QFrame::Shape::NoFrame); + m_inactivatedLanListWidget->setSpacing(LAN_LIST_SPACING); + m_inactivatedLanListWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_inactivatedLanListWidget->setVerticalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel); + m_inactivatedLanListWidget->verticalScrollBar()->setProperty("drawScrollBarGroove",false); //去除滚动条的外侧黑框 + m_inactivatedLanListWidget->verticalScrollBar()->setSingleStep(SCROLL_STEP); + m_inactivatedLanListWidget->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); + m_inactivatedAreaLayout->addWidget(m_inactivatedLanListWidget); + + QPalette pal = m_activatedLanListWidget->palette(); + pal.setBrush(QPalette::Base, QColor(0,0,0,0)); //背景透明 + m_activatedLanListWidget->setPalette(pal); + m_inactivatedLanListWidget->setPalette(pal); + + m_settingsLabel->installEventFilter(this); +} + +QListWidgetItem *LanPage::insertNewItem(KyConnectItem *itemData, QListWidget *listWidget) +{ + int index = 0; + + for(index = 0; index < m_inactivatedLanListWidget->count(); index++) { + QListWidgetItem *p_listWidgetItem = m_inactivatedLanListWidget->item(index); + LanListItem *p_lanItem = (LanListItem *)m_inactivatedLanListWidget->itemWidget(p_listWidgetItem); + QString name1 = p_lanItem->getConnectionName(); + QString name2 = itemData->m_connectName; + if (QString::compare(name1, name2, Qt::CaseInsensitive) > 0) { + break; + } + } + + QListWidgetItem *p_sortListWidgetItem = new QListWidgetItem(); + p_sortListWidgetItem->setFlags(p_sortListWidgetItem->flags() & (~Qt::ItemIsSelectable)); //设置不可被选中 + p_sortListWidgetItem->setSizeHint(QSize(listWidget->width(),ITEM_HEIGHT)); + + listWidget->insertItem(index, p_sortListWidgetItem); + + LanListItem *p_sortLanItem = nullptr; + p_sortLanItem = new LanListItem(itemData, m_currentDeviceName); + listWidget->setItemWidget(p_sortListWidgetItem, p_sortLanItem); + + return p_sortListWidgetItem; +} + +QListWidgetItem *LanPage::addNewItem(KyConnectItem *itemData, QListWidget *listWidget) +{ + QListWidgetItem *p_listWidgetItem = new QListWidgetItem(); + p_listWidgetItem->setFlags(p_listWidgetItem->flags() & (~Qt::ItemIsSelectable)); + p_listWidgetItem->setSizeHint(QSize(listWidget->width(), ITEM_HEIGHT)); + listWidget->addItem(p_listWidgetItem); + LanListItem *p_lanItem = nullptr; + if (itemData != nullptr) { + p_lanItem = new LanListItem(itemData, m_currentDeviceName); + qDebug() << "[LanPage] addNewItem, connection: " + << itemData->m_connectName << "deviceName: " << m_currentDeviceName; + } else { + p_lanItem = new LanListItem(); + qDebug() << "[LanPage] Add nullItem!"; + } + + listWidget->setItemWidget(p_listWidgetItem, p_lanItem); + return p_listWidgetItem; +} + +void LanPage::updateActivatedConnectionArea(KyConnectItem *p_newItem) +{ + if (m_activeConnectionMap.contains(p_newItem->m_connectUuid)) { + return; + } + + deleteConnectionMapItem(m_inactiveConnectionMap, m_inactivatedLanListWidget, p_newItem->m_connectUuid); + if (p_newItem->m_ifaceName == m_currentDeviceName) { + qDebug()<<"[LanPage]update active connection item"<m_connectName; + deleteConnectionMapItem(m_activeConnectionMap, m_activatedLanListWidget, EMPTY_CONNECT_UUID); + QListWidgetItem *p_listWidgetItem = addNewItem(p_newItem, m_activatedLanListWidget); + m_activeConnectionMap.insert(p_newItem->m_connectUuid, p_listWidgetItem); + this->showDesktopNotify(tr("LAN Connected Successfully")); + } + if (m_inactivatedLanListWidget->count() < MAX_ITEMS) { + m_inactivatedLanListWidget->setFixedWidth(MIN_WIDTH); + } + + return; +} + +void LanPage::updateConnectionArea(KyConnectItem *p_newItem) +{ + if (m_inactiveConnectionMap.contains(p_newItem->m_connectUuid)) { + return; + } + + deleteConnectionMapItem(m_activeConnectionMap, m_activatedLanListWidget, p_newItem->m_connectUuid); + if (m_activeConnectionMap.count() <= 0) { + addEmptyConnectItem(m_activeConnectionMap, m_activatedLanListWidget); + } + + if (p_newItem->m_ifaceName == m_currentDeviceName || p_newItem->m_ifaceName == "") { + qDebug()<<"[LanPage] update connection item"<m_connectName; + QListWidgetItem *p_listWidgetItem = insertNewItem(p_newItem, m_inactivatedLanListWidget); + m_inactiveConnectionMap.insert(p_newItem->m_connectUuid, p_listWidgetItem); + this->showDesktopNotify(tr("LAN Disconnected Successfully")); + } + if (m_inactivatedLanListWidget->count() < MAX_ITEMS) { + m_inactivatedLanListWidget->setFixedWidth(MIN_WIDTH); + } else { + m_inactivatedLanListWidget->setFixedWidth(MAX_WIDTH); + } + + return; +} + +void LanPage::updateConnectionState(QMap &connectMap, + QListWidget *lanListWidget, QString uuid, ConnectState state) +{ + qDebug() << LOG_FLAG << "update connection state"; + + QListWidgetItem *p_listWidgetItem = connectMap.value(uuid); + if (p_listWidgetItem) { + LanListItem *p_lanItem = (LanListItem *)lanListWidget->itemWidget(p_listWidgetItem); + p_lanItem->updateConnectionState(state); + } + + return; +} + +QString LanPage::getConnectionDevice(QString uuid) +{ + QString deviceName = ""; + + deviceName = m_activeResourse->getDeviceOfActivateConnect(uuid); + if (deviceName.isEmpty()) { + m_connectResourse->getInterfaceByUuid(deviceName, uuid); + } + + return deviceName; +} + +void LanPage::updateCurrentDevice(QString deviceName) +{ + if (m_currentDeviceName != deviceName) { + int index = m_deviceComboBox->findText(deviceName); + if (index < 0) { + index = 0; + } + m_deviceComboBox->setCurrentIndex(index); + return; + } + return; +} + +void LanPage::onConnectionStateChange(QString uuid, + NetworkManager::ActiveConnection::State state, + NetworkManager::ActiveConnection::Reason reason) +{ + //lanpage函数内持续监听连接状态的变化并记录供其他函数调用获取状态 + if (!m_connectResourse->isWiredConnection(uuid)) { + qDebug() << "[LanPage] connection state change signal but not wired"; + return; + } + + sendLanStateChangeSignal(uuid, (ConnectState)state); + + qDebug()<<"[LanPage] connection uuid"<< uuid + << "state change slot:"<< state; + + KyConnectItem *p_newItem = nullptr; + QString deviceName = ""; + + if (state == NetworkManager::ActiveConnection::State::Activated) { + p_newItem = m_activeResourse->getActiveConnectionByUuid(uuid); + if (nullptr == p_newItem) { + qWarning()<<"[LanPage] get active connection failed, connection uuid" << uuid; + return; + } + + deviceName = p_newItem->m_ifaceName; + updateActivatedConnectionArea(p_newItem); + updateConnectionState(m_activeConnectionMap, m_activatedLanListWidget, uuid, (ConnectState)state); + } else if (state == NetworkManager::ActiveConnection::State::Deactivated) { + p_newItem = m_connectResourse->getConnectionItemByUuid(uuid); + qDebug() << "[LanPage] deactivated reason" << reason; + if (nullptr == p_newItem) { + qWarning()<<"[LanPage] get active connection failed, connection uuid" << uuid; + return; + } + + deviceName = p_newItem->m_ifaceName; + updateConnectionArea(p_newItem); + updateConnectionState(m_inactiveConnectionMap, m_inactivatedLanListWidget, uuid, (ConnectState)state); + } else if (state == NetworkManager::ActiveConnection::State::Activating) { + deviceName = getConnectionDevice(uuid); + if (deviceName == m_currentDeviceName) { + updateConnectionState(m_inactiveConnectionMap, m_inactivatedLanListWidget, uuid, (ConnectState)state); + } + } else if (state == NetworkManager::ActiveConnection::State::Deactivating) { + deviceName = getConnectionDevice(uuid); + if (deviceName == m_currentDeviceName) { + updateConnectionState(m_activeConnectionMap, m_activatedLanListWidget, uuid, (ConnectState)state); + } + } + + emit lanActiveConnectionStateChanged(deviceName, uuid, state); + + if (p_newItem) { + delete p_newItem; + p_newItem = nullptr; + } + + return; +} + + +void LanPage::getWiredList(QMap > &map) +{ + QStringList devlist; + m_deviceResource->getNetworkDeviceList(NetworkManager::Device::Type::Ethernet, devlist); + if (devlist.isEmpty()) { + return; + } + + foreach (auto deviceName, devlist) { + QList activedList; + QList deactivedList; + QVector vector; + m_activeResourse->getActiveConnectionList(deviceName,NetworkManager::ConnectionSettings::Wired,activedList); + if (!activedList.isEmpty()) { + vector.append(QStringList() << activedList.at(0)->m_connectName << activedList.at(0)->m_connectUuid << activedList.at(0)->m_connectPath); + } else { + vector.append(QStringList()<<("--")); + } + + m_connectResourse->getConnectionList(deviceName, NetworkManager::ConnectionSettings::Wired, deactivedList); //未激活列表的显示 + if (!deactivedList.isEmpty()) { + for (int i = 0; i < deactivedList.size(); i++) { + vector.append(QStringList()<m_connectName<m_connectUuid << deactivedList.at(i)->m_connectPath); + } + } + map.insert(deviceName, vector); + } + return; +} + +void LanPage::sendLanUpdateSignal(KyConnectItem *p_connectItem) +{ + QStringList info; + info << p_connectItem->m_connectName << p_connectItem->m_connectUuid << p_connectItem->m_connectPath; + emit lanUpdate(p_connectItem->m_ifaceName, info); + + return; +} + +void LanPage::sendLanAddSignal(KyConnectItem *p_connectItem) +{ + QStringList info; + info << p_connectItem->m_connectName << p_connectItem->m_connectUuid << p_connectItem->m_connectPath; + qDebug() << "[LanPage] emit lanAdd because addConnection "; + emit lanAdd(p_connectItem->m_ifaceName, info); + + return; +} + +void LanPage::sendLanStateChangeSignal(QString uuid, ConnectState state) +{ + if (state == Activating || state == Deactivating) { + if (m_activeResourse->connectionIsVirtual(uuid)) { + return; + } + } + + emit this->lanConnectChanged(state); + + return; +} + +void LanPage::updateConnectionProperty(KyConnectItem *p_connectItem) +{ + QString newUuid = p_connectItem->m_connectUuid; + + if (m_inactiveConnectionMap.contains(newUuid)) { + QListWidgetItem *p_listWidgetItem = m_inactiveConnectionMap.value(newUuid); + LanListItem *p_lanItem = (LanListItem*)m_inactivatedLanListWidget->itemWidget(p_listWidgetItem); + if (p_connectItem->m_ifaceName != "" + && m_currentDeviceName != p_connectItem->m_ifaceName) { + m_inactivatedLanListWidget->removeItemWidget(p_listWidgetItem); + + delete p_listWidgetItem; + p_listWidgetItem = nullptr; + + delete p_lanItem; + p_lanItem = nullptr; + + m_inactiveConnectionMap.remove(newUuid); + } else { + if (p_connectItem->m_connectName != p_lanItem->getConnectionName()){ + //只要名字改变就要删除,重新插入,主要是为了排序 + deleteConnectionMapItem(m_inactiveConnectionMap, m_inactivatedLanListWidget, newUuid); + QListWidgetItem *p_sortListWidgetItem = insertNewItem(p_connectItem, m_inactivatedLanListWidget); + if (m_inactiveConnectionMap.contains(newUuid)) { + qDebug()<m_connectPath != p_lanItem->getConnectionPath()) { + p_lanItem->updateConnectionPath(p_connectItem->m_connectPath); + } + } + + } else if (!m_activeConnectionMap.contains(newUuid)){ + if (p_connectItem->m_ifaceName == m_currentDeviceName + || p_connectItem->m_ifaceName.isEmpty()) { + QListWidgetItem *p_listWidgetItem = insertNewItem(p_connectItem, m_inactivatedLanListWidget); + if (m_inactiveConnectionMap.contains(newUuid)) { + qDebug()<m_connectUuid; + + if (m_activeConnectionMap.contains(newUuid)) { + QListWidgetItem *p_listWidgetItem = m_activeConnectionMap.value(newUuid); + LanListItem *p_lanItem = (LanListItem *)m_activatedLanListWidget->itemWidget(p_listWidgetItem); + if (m_currentDeviceName != p_connectItem->m_ifaceName) { + m_activeConnectionMap.remove(newUuid); + int takeRow = m_activatedLanListWidget->row(p_listWidgetItem); + m_activatedLanListWidget->takeItem(takeRow); + + delete p_lanItem; + p_lanItem = nullptr; + + p_lanItem = new LanListItem(); + m_activatedLanListWidget->addItem(p_listWidgetItem); + m_activatedLanListWidget->setItemWidget(p_listWidgetItem, p_lanItem); + m_activeConnectionMap.insert(EMPTY_CONNECT_UUID, p_listWidgetItem); + } else { + if (p_lanItem->getConnectionName() != p_connectItem->m_connectName) { + p_lanItem->updateConnectionName(p_connectItem->m_connectName); + } + + if (p_lanItem->getConnectionName() != p_connectItem->m_connectPath) { + p_lanItem->updateConnectionPath(p_connectItem->m_connectPath); + } + + } + } + + return; +} + +void LanPage::onUpdateConnection(QString uuid) +{ + if (!m_connectResourse->isWiredConnection(uuid)) { + return; + } + + qDebug() << "[LanPage]:Connection property Changed." << Q_FUNC_INFO << __LINE__; + + KyConnectItem *p_newItem = nullptr; + if (m_connectResourse->isActivatedConnection(uuid)) { + p_newItem = m_activeResourse->getActiveConnectionByUuid(uuid); + if (nullptr == p_newItem) { + qWarning()<<"[LanPage] get item failed, when update activate connection." + <<"connection uuid" << uuid; + return; + } + + updateActiveConnectionProperty(p_newItem); + } else { + p_newItem = m_connectResourse->getConnectionItemByUuid(uuid); + if (nullptr == p_newItem) { + qWarning()<<"[LanPage] get item failed, when update connection." + <<"connection uuid"<type() == QEvent::MouseButtonRelease) { + onShowControlCenter(); + } + } + + return QWidget::eventFilter(watched, event); +} + +void LanPage::activateWired(const QString& devName, const QString& connUuid) +{ + qDebug() << "[LanPage] activateWired" << devName << connUuid; + if (!m_deviceResource->wiredDeviceIsCarriered(devName)) { + qDebug() << LOG_FLAG << devName << "is not carried, so can not activate connection"; + this->showDesktopNotify(tr("Wired Device not carried")); + } else { + m_wiredConnectOperation->activateConnection(connUuid, devName); + } +} + +void LanPage::deactivateWired(const QString& devName, const QString& connUuid) +{ + qDebug() << "[LanPage] deactivateWired" << devName << connUuid; + QString name(""); + m_wiredConnectOperation->deactivateWiredConnection(name, connUuid); +} + +void LanPage::showDetailPage(QString devName, QString uuid) +{ + KyConnectItem *p_item = nullptr; + bool isActive = true; + + if (m_connectResourse->isActivatedConnection(uuid)) { + p_item = m_activeResourse->getActiveConnectionByUuid(uuid); + isActive = true; + } else { + p_item = m_connectResourse->getConnectionItemByUuid(uuid); + isActive = false; + } + + if (nullptr == p_item) { + qWarning()<<"[LanPage] GetConnectionItemByUuid is empty when showDetailPage." + <<"device name"<m_connectName, uuid, isActive, false, false, this); + netDetail->show(); + + delete p_item; + p_item = nullptr; +} + +bool LanPage::lanIsConnected() +{ + if (m_activeResourse->wiredConnectIsActived()) { + return true; + } else { + return false; + } +} + diff --git a/src/frontend/tab-pages/lanpage.h b/src/frontend/tab-pages/lanpage.h new file mode 100644 index 00000000..ee2d6988 --- /dev/null +++ b/src/frontend/tab-pages/lanpage.h @@ -0,0 +1,135 @@ +#ifndef LANPAGE_H +#define LANPAGE_H + +#include "divider.h" +#include "switchbutton.h" +#include +#include +#include +#include +#include +#include +#include + +#include "list-items/listitem.h" +#include "list-items/lanlistitem.h" +#include "tab-pages/tabpage.h" + +class LanListItem; + +class LanPage : public TabPage +{ + Q_OBJECT +public: + explicit LanPage(QWidget *parent = nullptr); + ~LanPage(); + + //for dbus + void getWiredList(QMap > &map); + void activateWired(const QString& devName, const QString& connUuid); + void deactivateWired(const QString& devName, const QString& connUuid); + void showDetailPage(QString devName, QString uuid); + void setWiredDeviceEnable(const QString& devName, bool enable); + + bool lanIsConnected(); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + void initLanDevice(); + void initUI(); + void initLanArea(); + void initNetSwitch(); + void initLanDeviceState(); + + void initDeviceCombox(); + void updateDeviceCombox(QString oldDeviceName, QString newDeviceName); + void deleteDeviceFromCombox(QString deviceName); + void addDeviceForCombox(QString deviceName); + + QListWidgetItem *insertNewItem(KyConnectItem *itemData, QListWidget *listWidget); + QListWidgetItem *addNewItem(KyConnectItem *itemData, QListWidget *listWidget); + bool removeConnectionItem(QMap &connectMap, + QListWidget *lanListWidget, QString path); + + void getEnabledDevice(QStringList &enableDeviceList); + void getDisabledDevices(QStringList &disableDeviceList); + + void constructConnectionArea(); + void constructActiveConnectionArea(); + + void updateConnectionArea(KyConnectItem *p_newItem); + void updateActivatedConnectionArea(KyConnectItem *p_newItem); + void updateConnectionState(QMap &connectMap, + QListWidget *lanListWidget, QString uuid, ConnectState state); + QString getConnectionDevice(QString uuid); + + void updateActiveConnectionProperty(KyConnectItem *p_connectItem); + void updateConnectionProperty(KyConnectItem *p_connectItem); + + void sendLanUpdateSignal(KyConnectItem *p_connectItem); + void sendLanAddSignal(KyConnectItem *p_connectItem); + void sendLanStateChangeSignal(QString uuid, ConnectState state); + + void addEmptyConnectItem(QMap &connectMap, + QListWidget *lanListWidget); + void clearConnectionMap(QMap &connectMap, + QListWidget *lanListWidget); + void deleteConnectionMapItem(QMap &connectMap, + QListWidget *lanListWidget, QString uuid); + + void updateCurrentDevice(QString deviceName); + +signals: + void lanAdd(QString devName, QStringList info); + void lanRemove(QString dbusPath); + void lanUpdate(QString devName, QStringList info); + + void lanActiveConnectionStateChanged(QString interface, QString uuid, int status); + void lanConnectChanged(int state); + +private slots: + void onConnectionStateChange(QString uuid, NetworkManager::ActiveConnection::State state, + NetworkManager::ActiveConnection::Reason reason); + + void onAddConnection(QString uuid); + void onRemoveConnection(QString path); + void onUpdateConnection(QString uuid); + + void onSwithGsettingsChanged(const QString &key); + void onLanSwitchClicked(); + + void onDeviceAdd(QString deviceName, NetworkManager::Device::Type deviceType); + void onDeviceRemove(QString deviceName); + void onDeviceNameUpdate(QString oldName, QString newName); + + void onDeviceCarriered(QString deviceName, bool pluged); + void onDeviceActiveChanage(QString deviceName, bool deviceActive); + + void onDeviceComboxIndexChanged(int currentIndex); + + void onShowControlCenter(); + +private: + QListWidget * m_activatedLanListWidget = nullptr; + QListWidget * m_inactivatedLanListWidget = nullptr; + + KyNetworkDeviceResourse *m_deviceResource = nullptr; + KyWiredConnectOperation *m_wiredConnectOperation = nullptr; + KyActiveConnectResourse *m_activeResourse = nullptr; //激活的连接 + KyConnectResourse *m_connectResourse = nullptr; //未激活的连接 + + QMap m_inactiveConnectionMap; + QMap m_activeConnectionMap; + + QString m_currentDeviceName; + QStringList m_devList; + QStringList m_enableDeviceList; + + QGSettings *m_switchGsettings = nullptr; + + bool m_wiredSwitch = true; +}; + +#endif // LANPAGE_H diff --git a/src/frontend/tab-pages/tab-pages.pri b/src/frontend/tab-pages/tab-pages.pri new file mode 100644 index 00000000..6d049be2 --- /dev/null +++ b/src/frontend/tab-pages/tab-pages.pri @@ -0,0 +1,12 @@ +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/lanpage.h \ + $$PWD/wlanpage.h \ + $$PWD/tabpage.h + +SOURCES += \ + $$PWD/lanpage.cpp \ + $$PWD/wlanpage.cpp \ + $$PWD/tabpage.cpp + diff --git a/src/frontend/tab-pages/tabpage.cpp b/src/frontend/tab-pages/tabpage.cpp new file mode 100644 index 00000000..b1d73308 --- /dev/null +++ b/src/frontend/tab-pages/tabpage.cpp @@ -0,0 +1,307 @@ +#include "tabpage.h" +#include +#include +#include +#include + +TabPage::TabPage(QWidget *parent) : QWidget(parent) +{ + initUI(); + connect(qApp, &QApplication::paletteChanged, this, &TabPage::onPaletteChanged); +} + +TabPage::~TabPage() +{ + delete m_titleDivider; + delete m_activatedNetDivider; + delete m_inactivatedNetDivider; +} + +void TabPage::initUI() +{ + m_mainLayout = new QVBoxLayout(this); + m_mainLayout->setContentsMargins(MAIN_LAYOUT_MARGINS); + m_mainLayout->setSpacing(MAIN_LAYOUT_SPACING); + this->setLayout(m_mainLayout); + + m_titleFrame = new QFrame(this); + m_titleFrame->setFixedHeight(TITLE_FRAME_HEIGHT); + m_titleLayout = new QHBoxLayout(m_titleFrame); + m_titleLayout->setContentsMargins(TITLE_LAYOUT_MARGINS); + m_titleLabel = new QLabel(m_titleFrame); + m_netSwitch = new SwitchButton(m_titleFrame); + m_titleLayout->addWidget(m_titleLabel); + m_titleLayout->addStretch(); + m_titleLayout->addWidget(m_netSwitch); + m_titleDivider = new Divider(this); + + //临时增加的下拉框选择网卡区域 + m_deviceFrame = new QFrame(this); + m_deviceFrame->setFixedHeight(TITLE_FRAME_HEIGHT); + m_deviceLayout = new QHBoxLayout(m_deviceFrame); + m_deviceLayout->setContentsMargins(DEVICE_LAYOUT_MARGINS); + m_deviceFrame->setLayout(m_deviceLayout); + m_deviceLabel = new QLabel(m_deviceFrame); + m_deviceLabel->setText(tr("Current Device")); + m_deviceComboBox = new QComboBox(m_deviceFrame); + m_deviceComboBox->setFixedWidth(DEVICE_COMBOBOX_WIDTH); + + m_tipsLabel = new QLabel(m_deviceFrame); + m_tipsLabel->setText(tr("Devices Closed!")); + m_deviceLayout->addWidget(m_deviceLabel); + m_deviceLayout->addStretch(); + m_deviceLayout->addWidget(m_deviceComboBox); + m_deviceLayout->addWidget(m_tipsLabel); + connect(m_deviceComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &TabPage::onDeviceComboxIndexChanged); + + m_activatedNetFrame = new QFrame(this); + m_activatedNetFrame->setMaximumHeight(ACTIVE_AREA_MAX_HEIGHT); + m_activatedNetLayout = new QVBoxLayout(m_activatedNetFrame); + m_activatedNetLayout->setContentsMargins(ACTIVE_NET_LAYOUT_MARGINS); +// m_activatedNetLayout->setSpacing(NET_LAYOUT_SPACING); + m_activatedNetLabel = new QLabel(m_activatedNetFrame); + m_activatedNetLabel->setContentsMargins(TEXT_MARGINS); + m_activatedNetLayout->addWidget(m_activatedNetLabel); + m_activatedNetDivider = new Divider(this); + + m_inactivatedNetFrame = new QFrame(this); + m_inactivatedNetFrame->setMinimumHeight(INACTIVE_AREA_MIN_HEIGHT); + m_inactivatedNetLayout = new QVBoxLayout(m_inactivatedNetFrame); + m_inactivatedNetLayout->setContentsMargins(NET_LAYOUT_MARGINS); +// m_inactivatedNetLayout->setSpacing(NET_LAYOUT_SPACING); + m_inactivatedNetFrame->setLayout(m_inactivatedNetLayout); + + m_inactivatedNetLabel = new QLabel(m_inactivatedNetFrame); + m_inactivatedNetLabel->setContentsMargins(TEXT_MARGINS); + + m_inactivatedNetListArea = new QScrollArea(m_inactivatedNetFrame); + m_inactivatedNetListArea->setFrameShape(QFrame::Shape::NoFrame); + m_inactivatedNetListArea->setWidgetResizable(true); + m_inactivatedNetListArea->setBackgroundRole(QPalette::Base); + m_inactivatedNetListArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_inactivatedNetListArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_inactivatedAreaLayout = new QVBoxLayout(m_inactivatedNetListArea); + m_inactivatedAreaLayout->setSpacing(MAIN_LAYOUT_SPACING); + m_inactivatedAreaLayout->setContentsMargins(MAIN_LAYOUT_MARGINS); + m_inactivatedNetListArea->setLayout(m_inactivatedAreaLayout); + + m_inactivatedNetLayout->addWidget(m_inactivatedNetLabel); + m_inactivatedNetLayout->addWidget(m_inactivatedNetListArea); + + m_inactivatedNetDivider = new Divider(this); + m_settingsFrame = new QFrame(this); + m_settingsFrame->setFixedHeight(TITLE_FRAME_HEIGHT); + + m_settingsLayout = new QHBoxLayout(m_settingsFrame); + m_settingsLayout->setContentsMargins(SETTINGS_LAYOUT_MARGINS); + m_settingsLabel = new KyLable(m_settingsFrame); + m_settingsLabel->setCursor(Qt::PointingHandCursor); + m_settingsLabel->setText(tr("Settings")); + m_settingsLabel->setScaledContents(true); + + m_settingsLayout->addWidget(m_settingsLabel); + m_settingsLayout->addStretch(); + m_settingsFrame->setLayout(m_settingsLayout); + + m_mainLayout->addWidget(m_titleFrame); + //临时增加的设备选择区域 + m_mainLayout->addWidget(m_deviceFrame); + m_mainLayout->addWidget(m_titleDivider); + m_mainLayout->addWidget(m_activatedNetFrame); + m_mainLayout->addWidget(m_activatedNetDivider); + m_mainLayout->addWidget(m_inactivatedNetFrame); + m_mainLayout->addStretch(); + m_mainLayout->addWidget(m_inactivatedNetDivider); + m_mainLayout->addWidget(m_settingsFrame); + + QPalette pal = m_inactivatedNetListArea->palette(); + pal.setBrush(QPalette::Base, QColor(0,0,0,0)); //背景透明 + m_inactivatedNetListArea->setPalette(pal); + + onPaletteChanged(); +} + +void TabPage::onPaletteChanged() +{ + QPalette labPal = m_activatedNetLabel->palette(); + QColor color = qApp->palette().color(QPalette::PlaceholderText); + labPal.setColor(QPalette::WindowText, color); + m_activatedNetLabel->setPalette(labPal); + m_inactivatedNetLabel->setPalette(labPal); + + if (m_deviceComboBox->view()) { + QPalette view_pal = m_deviceComboBox->view()->palette(); + QColor view_color = qApp->palette().color(QPalette::Active, QPalette::Button); + view_pal.setColor(QPalette::Base, view_color); + m_deviceComboBox->setPalette(view_pal); + m_deviceComboBox->view()->setPalette(view_pal); + } +} + +void TabPage::showDesktopNotify(const QString &message) +{ + QDBusInterface iface("org.freedesktop.Notifications", + "/org/freedesktop/Notifications", + "org.freedesktop.Notifications", + QDBusConnection::sessionBus()); + QList args; + args<<(tr("Kylin NM")) + <<((unsigned int) 0) + <beginGroup("DEFAULTCARD"); + defaultDevice = m_settings->value(key).toString(); + m_settings->endGroup(); + + delete m_settings; + m_settings = nullptr; + + return defaultDevice; +} + +void setDefaultDevice(KyDeviceType deviceType, QString deviceName) +{ + QString key; + switch (deviceType) { + case WIRED: + key = "wired"; + break; + case WIRELESS: + key = "wireless"; + break; + default: + return; + } + + QSettings * m_settings = new QSettings(CONFIG_FILE_PATH, QSettings::IniFormat); + m_settings->beginGroup("DEFAULTCARD"); + m_settings->setValue(key, deviceName); + m_settings->endGroup(); + m_settings->sync(); + + delete m_settings; + m_settings = nullptr; + + return; +} + +bool checkDeviceExist(KyDeviceType deviceType, QString deviceName) +{ + NetworkManager::Device::Type type; + switch (deviceType) { + case WIRED: + type = NetworkManager::Device::Type::Ethernet; + break; + case WIRELESS: + type = NetworkManager::Device::Type::Wifi; + break; + default: + return false; + break; + } + + KyNetworkDeviceResourse * kdr = new KyNetworkDeviceResourse(); + QStringList devList; + devList.clear(); + + kdr->getNetworkDeviceList(type, devList); + delete kdr; + return devList.contains(deviceName); +} + +void saveDeviceEnableState(QString deviceName, bool enable) +{ + QSettings * m_settings = new QSettings(CONFIG_FILE_PATH, QSettings::IniFormat); + m_settings->beginGroup("CARDEABLE"); + m_settings->setValue(deviceName, enable); + m_settings->endGroup(); + m_settings->sync(); + delete m_settings; + m_settings = nullptr; + return; +} + +void deleteDeviceEnableState(QString deviceName) +{ + QSettings * m_settings = new QSettings(CONFIG_FILE_PATH, QSettings::IniFormat); + m_settings->beginGroup("CARDEABLE"); + m_settings->remove(deviceName); + m_settings->endGroup(); + m_settings->sync(); + delete m_settings; + m_settings = nullptr; + return; +} + +void getDeviceEnableState(int type, QMap &map) +{ + map.clear(); + if (!QFile::exists(CONFIG_FILE_PATH)) { + qDebug() << "CONFIG_FILE_PATH not exist"; + return; + } + if (type != WIRED && type != WIRELESS) { + qDebug() << "getDeviceEnableState but wrong type"; + return; + } + + KyNetworkDeviceResourse * kdr = new KyNetworkDeviceResourse(); + QStringList wiredDevList,wirelessDevList; + wiredDevList.clear(); + wirelessDevList.clear(); + + QSettings * m_settings = new QSettings(CONFIG_FILE_PATH, QSettings::IniFormat); + m_settings->beginGroup("CARDEABLE"); + + if (type == WIRED) { + kdr->getNetworkDeviceList(NetworkManager::Device::Type::Ethernet, wiredDevList); + if (!wiredDevList.isEmpty()) { + for (int i = 0; i < wiredDevList.size(); ++i) { + if (!m_settings->contains(wiredDevList.at(i))) { + saveDeviceEnableState(wiredDevList.at(i),true); + } + bool enable = m_settings->value(wiredDevList.at(i), true).toBool(); + map.insert(wiredDevList.at(i), enable); + } + } + } else if (type == WIRELESS) { + kdr->getNetworkDeviceList(NetworkManager::Device::Type::Wifi, wirelessDevList); + if (!wirelessDevList.isEmpty()) { + for (int i = 0; i < wirelessDevList.size(); ++i) { + bool enable = m_settings->value(wirelessDevList.at(i), true).toBool(); + map.insert(wirelessDevList.at(i), enable); + } + } + } + + m_settings->endGroup(); + delete m_settings; + m_settings = nullptr; + delete kdr; + kdr = nullptr; + return; +} diff --git a/src/frontend/tab-pages/tabpage.h b/src/frontend/tab-pages/tabpage.h new file mode 100644 index 00000000..d8bd8712 --- /dev/null +++ b/src/frontend/tab-pages/tabpage.h @@ -0,0 +1,131 @@ +#ifndef TABPAGE_H +#define TABPAGE_H + +#include "divider.h" +#include "switchbutton.h" +#include "kylable.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "kylinnetworkdeviceresource.h" + +#define MAIN_LAYOUT_MARGINS 0,0,0,0 +#define MAIN_LAYOUT_SPACING 0 +#define TITLE_FRAME_HEIGHT 50 //TabWidget的tab和widget有间隙,和设计稿看起来一致就不能设为设计稿里的高度 +#define TITLE_LAYOUT_MARGINS 24,0,24,0 +#define DEVICE_LAYOUT_MARGINS 24,0,24,8 +#define DEVICE_COMBOBOX_WIDTH 180 +#define ACTIVE_NET_LAYOUT_MARGINS 8,8,8,8 +#define NET_LAYOUT_MARGINS 8,8,0,3 +#define NET_LAYOUT_SPACING 8 +#define NET_LIST_SPACING 0 +#define TEXT_MARGINS 16,0,0,0 +//#define SCROLL_AREA_HEIGHT 200 +#define SETTINGS_LAYOUT_MARGINS 24,0,24,0 +#define TRANSPARENT_COLOR QColor(0,0,0,0) +#define INACTIVE_AREA_MIN_HEIGHT 170 +#define ACTIVE_AREA_MAX_HEIGHT 92 + +#define MAX_ITEMS 4 +#define MAX_WIDTH 400 +#define MIN_WIDTH 383 + +#define SCROLL_STEP 4 + +enum KyDeviceType +{ + WIRED, + WIRELESS +}; + +const QString CONFIG_FILE_PATH = QDir::homePath() + "/.config/ukui/kylin-nm.conf"; +bool checkDeviceExist(KyDeviceType deviceType, QString deviceName); +QString getDefaultDeviceName(KyDeviceType deviceType); +void setDefaultDevice(KyDeviceType deviceType, QString deviceName); +void saveDeviceEnableState(QString deviceName, bool enable); +void deleteDeviceEnableState(QString deviceName); +void getDeviceEnableState(int type, QMap &map); + +class TabPage : public QWidget +{ + Q_OBJECT +public: + explicit TabPage(QWidget *parent = nullptr); + ~TabPage(); + +// void updateDefaultDevice(QString &deviceName); +// QString getDefaultDevice(); + static void showDesktopNotify(const QString &message); + + void hideSetting() { + if (nullptr != m_settingsFrame) { + m_settingsFrame->hide(); + m_inactivatedNetDivider->hide(); + m_inactivatedNetFrame->setMinimumHeight(INACTIVE_AREA_MIN_HEIGHT + 100); + } + } + void showSetting() { + if (nullptr != m_settingsFrame) { + m_inactivatedNetFrame->setMinimumHeight(INACTIVE_AREA_MIN_HEIGHT); + m_settingsFrame->show(); + m_inactivatedNetDivider->show(); + } + } + +signals: + void deviceStatusChanged(); + void deviceNameChanged(QString oldName, QString newName, int type); + void activateFailed(QString errorMessage); + void deactivateFailed(QString errorMessage); + +protected: + void initUI(); +// virtual void initDevice() = 0;//初始化默认设备 + virtual void initDeviceCombox() = 0;//初始化设备选择下拉框 + QVBoxLayout * m_mainLayout = nullptr; + QFrame * m_titleFrame = nullptr; + QHBoxLayout * m_titleLayout = nullptr; + QLabel * m_titleLabel = nullptr; + SwitchButton * m_netSwitch = nullptr; + Divider * m_titleDivider = nullptr; + + QFrame * m_activatedNetFrame = nullptr; + QVBoxLayout * m_activatedNetLayout = nullptr; + QLabel * m_activatedNetLabel = nullptr; + Divider * m_activatedNetDivider = nullptr; + + QFrame * m_inactivatedNetFrame = nullptr; + QVBoxLayout * m_inactivatedNetLayout = nullptr; + QLabel * m_inactivatedNetLabel = nullptr; + QScrollArea * m_inactivatedNetListArea = nullptr; + QVBoxLayout * m_inactivatedAreaLayout = nullptr; + + Divider * m_inactivatedNetDivider = nullptr; + + QFrame * m_settingsFrame = nullptr; + QHBoxLayout * m_settingsLayout = nullptr; + KyLable * m_settingsLabel = nullptr; + + //临时增加的下拉框选择网卡区域 + QFrame * m_deviceFrame = nullptr; + QHBoxLayout * m_deviceLayout = nullptr; + QLabel * m_deviceLabel = nullptr; + QComboBox * m_deviceComboBox = nullptr; + QLabel * m_tipsLabel = nullptr; + + + +public slots: + virtual void onDeviceComboxIndexChanged(int currentIndex) = 0; + void onPaletteChanged(); + +}; + +#endif // TABPAGE_H diff --git a/src/frontend/tab-pages/wlanpage.cpp b/src/frontend/tab-pages/wlanpage.cpp new file mode 100644 index 00000000..935c78fb --- /dev/null +++ b/src/frontend/tab-pages/wlanpage.cpp @@ -0,0 +1,1453 @@ +#include "wlanpage.h" +#include "kywirelessnetitem.h" +#include +#include +#include +#include +#include + +#define AP_SCAN_INTERVAL (20*1000) +#define ICON_REFRESH_INTERVAL (5*1000) +#define EMPTY_SSID "emptyssid" +#define LOG_FLAG "[WlanPage]" +#define LAN_PAGE_INDEX 0 + +const QString NotApConnection = "0"; +const QString IsApConnection = "1"; + +WlanPage::WlanPage(QWidget *parent) : TabPage(parent) +{ + m_wirelessNetResource = new KyWirelessNetResource(this); + m_activatedConnectResource = new KyActiveConnectResourse(this); + m_netDeviceResource=new KyNetworkDeviceResourse(this); + m_connectResource = new KyConnectResourse(this); + m_wirelessConnectOpreation = new KyWirelessConnectOperation(this); + + initDevice(); + initWlanUI(); + initWlanSwitchState(); + initDeviceCombox(); + initWlanArea(); + + initTimer(); + + connect(m_wirelessNetResource, &KyWirelessNetResource::wifiNetworkAdd, this, &WlanPage::onWlanAdded); + connect(m_wirelessNetResource, &KyWirelessNetResource::wifiNetworkRemove, this, &WlanPage::onWlanRemoved); + + connect(m_wirelessNetResource, &KyWirelessNetResource::signalStrengthChange, this, &WlanPage::signalStrengthChange); + connect(m_wirelessNetResource, &KyWirelessNetResource::secuTypeChange, this, &WlanPage::onSecurityTypeChange); + + connect(m_wirelessNetResource, &KyWirelessNetResource::connectionAdd, this, &WlanPage::onConnectionAdd); + connect(m_wirelessNetResource, &KyWirelessNetResource::connectionRemove, this, &WlanPage::onConnectionRemove); + + connect(m_activatedConnectResource, &KyActiveConnectResourse::stateChangeReason, + this, &WlanPage::onConnectionStateChanged); + + connect(m_netDeviceResource, &KyNetworkDeviceResourse::deviceAdd, this, &WlanPage::onDeviceAdd); + connect(m_netDeviceResource, &KyNetworkDeviceResourse::deviceRemove, this, &WlanPage::onDeviceRemove); + connect(m_netDeviceResource, &KyNetworkDeviceResourse::deviceNameUpdate, this, &WlanPage::onDeviceNameUpdate); + + connect(m_wirelessConnectOpreation, &KyWirelessConnectOperation::activateConnectionError, this, &WlanPage::activateFailed); + connect(m_wirelessConnectOpreation, &KyWirelessConnectOperation::addAndActivateConnectionError, this, &WlanPage::activateFailed); + connect(m_wirelessConnectOpreation, &KyWirelessConnectOperation::deactivateConnectionError, this, &WlanPage::deactivateFailed); + + connect(m_wirelessConnectOpreation, &KyWirelessConnectOperation::wifiEnabledChanged, this, &WlanPage::onWifiEnabledChanged); + + connect(m_connectResource, &KyConnectResourse::connectivityChanged, this, &WlanPage::connectivityChanged); +} + +bool WlanPage::eventFilter(QObject *w, QEvent *e) +{ + if (e->type() == QEvent::MouseButtonRelease) { + if (w == m_settingsLabel) { + //ZJP_TODO 打开控制面板 + qDebug() << LOG_FLAG <<"recive event show control center"; + showControlCenter(); + } + } + + return QWidget::eventFilter(w,e); +} + +void WlanPage::initWlanUI() +{ + m_titleLabel->setText(tr("WLAN")); + + m_activatedNetLabel->setText(tr("Activated WLAN")); + m_activatedNetListWidget = new QListWidget(m_activatedNetFrame); + m_activatedNetListWidget->setFrameShape(QFrame::Shape::NoFrame); + m_activatedNetListWidget->setContentsMargins(MAIN_LAYOUT_MARGINS); + m_activatedNetListWidget->setSpacing(NET_LIST_SPACING); + m_activatedNetListWidget->setFixedHeight(NORMAL_HEIGHT); + m_activatedNetListWidget->setFixedWidth(MIN_WIDTH); + m_activatedNetListWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_activatedNetLayout->addWidget(m_activatedNetListWidget); + + m_inactivatedNetLabel->setText(tr("Other WLAN")); + m_inactivatedNetListWidget = new QListWidget(m_inactivatedNetListArea); + m_inactivatedNetListWidget->setContentsMargins(MAIN_LAYOUT_MARGINS); + m_inactivatedNetListWidget->setSpacing(NET_LIST_SPACING); + m_inactivatedNetListWidget->setFrameShape(QFrame::Shape::NoFrame); + m_inactivatedNetListWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_inactivatedNetListWidget->setVerticalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel); + m_inactivatedNetListWidget->verticalScrollBar()->setProperty("drawScrollBarGroove",false); //去除滚动条的外侧黑框 + m_inactivatedNetListWidget->verticalScrollBar()->setSingleStep(SCROLL_STEP); + m_inactivatedNetListWidget->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); + addWlanMoreItem(); + m_inactivatedAreaLayout->addWidget(m_inactivatedNetListWidget); + + QPalette pal = m_activatedNetListWidget->palette(); + pal.setBrush(QPalette::Base, QColor(0,0,0,0)); //背景透明 + m_activatedNetListWidget->setPalette(pal); + m_inactivatedNetListWidget->setPalette(pal); + + m_settingsLabel->installEventFilter(this); +} + + +void WlanPage::onWlanSwithGsettingsChanged(const QString &key) +{ + if (key == WIRELESS_SWITCH) { + m_wlanSwitchEnable = m_switchGsettings->get(WIRELESS_SWITCH).toBool(); + qDebug() << LOG_FLAG << "wlan switch state" << m_wlanSwitchEnable; + m_netSwitch->setSwitchStatus(m_wlanSwitchEnable); + initDeviceCombox(); + initWlanArea(); + } + + return; +} + +/** + * @brief WlanPage::onWlanSwitchClicked 点击无线网开关 + */ +void WlanPage::onWlanSwitchClicked() +{ + if (m_devList.isEmpty()) { + showDesktopNotify(tr("No wireless network card detected")); + //检测不到无线网卡不再触发click信号 + m_netSwitch->setSwitchStatus(false); + m_netSwitch->setEnabled(false); + } else { + bool switchEnable = m_netSwitch->getSwitchStatus(); + if (m_wlanSwitchEnable != switchEnable) { + qDebug()<< LOG_FLAG << "wlan switch state " << switchEnable; + m_wirelessConnectOpreation->setWirelessEnabled(switchEnable); + if (!switchEnable) { + m_netSwitch->setEnabled(false); + m_activatedNetFrame->hide(); + m_activatedNetDivider->hide(); + m_inactivatedNetFrame->hide(); + m_deviceFrame->hide(); + } + } + } + + return; +} + +void WlanPage::initWlanSwitchState() +{ + m_wlanSwitchEnable = m_wirelessConnectOpreation->getWirelessEnabled(); + + if (QGSettings::isSchemaInstalled(GSETTINGS_SCHEMA)) { + m_switchGsettings = new QGSettings(GSETTINGS_SCHEMA); + if (m_switchGsettings->keys().contains(WIRELESS_SWITCH)) { + if (m_devList.isEmpty()) { + m_wlanSwitchEnable = false; + m_netSwitch->setSwitchStatus(m_wlanSwitchEnable); + m_netSwitch->setEnabled(false); + } else { + m_wlanSwitchEnable = m_switchGsettings->get(WIRELESS_SWITCH).toBool(); + } + connect(m_switchGsettings, &QGSettings::changed, this, &WlanPage::onWlanSwithGsettingsChanged); + } + } + m_netSwitch->setSwitchStatus(m_wlanSwitchEnable); + + + connect(m_netSwitch, &SwitchButton::clicked, this, &WlanPage::onWlanSwitchClicked); + + return; +} + +void WlanPage::initTimer() +{ + m_scanTimer = new QTimer(this); + connect(m_scanTimer, &QTimer::timeout, this, &WlanPage::requestScan); + + m_refreshIconTimer = new QTimer(this); + connect(m_refreshIconTimer, &QTimer::timeout, this, &WlanPage::onRefreshIconTimer); + m_refreshIconTimer->start(ICON_REFRESH_INTERVAL); +} + +/** + * @brief WlanPage::initDevice 初始化默认网卡 + */ +void WlanPage::initDevice() +{ + m_devList.clear(); + m_netDeviceResource->getNetworkDeviceList(NetworkManager::Device::Type::Wifi, m_devList); + + m_currentDevice = getDefaultDeviceName(WIRELESS); + return; +} + +void WlanPage::initDeviceCombox() +{ + //TODO 获取设备列表,单设备时隐藏下拉框,多设备时添加到下拉框 + disconnect(m_deviceComboBox, QOverload::of(&QComboBox::currentIndexChanged), + this, &WlanPage::onDeviceComboxIndexChanged); + m_deviceComboBox->clear(); + + if (m_wlanSwitchEnable) { + if (0 == m_devList.count()) { + m_deviceFrame->show(); + m_tipsLabel->show(); + m_deviceComboBox->hide(); + m_currentDevice = ""; + setDefaultDevice(WIRELESS, m_currentDevice); + } else if (1 == m_devList.count()) { + m_deviceFrame->hide(); + if (m_currentDevice != m_devList.at(0)) { + m_currentDevice = m_devList.at(0); + setDefaultDevice(WIRELESS, m_currentDevice); + } + } else { + m_deviceFrame->show(); + m_deviceComboBox->show(); + m_tipsLabel->hide(); + for (int index = 0; index < m_devList.count(); ++index) { + m_deviceComboBox->addItem(m_devList.at(index)); + } + + if (m_devList.contains(m_currentDevice)) { + m_deviceComboBox->setCurrentText(m_currentDevice); + } else { + m_currentDevice = m_deviceComboBox->currentText(); + setDefaultDevice(WIRELESS, m_currentDevice); + } + } + } else { + m_deviceFrame->hide(); + m_currentDevice = ""; + setDefaultDevice(WIRELESS, m_currentDevice); + } + + connect(m_deviceComboBox, QOverload::of(&QComboBox::currentIndexChanged), + this, &WlanPage::onDeviceComboxIndexChanged, Qt::DirectConnection); + return; +} + +QListWidgetItem *WlanPage::addEmptyItem(QListWidget *wirelessListWidget) +{ + WlanListItem *p_wlanItem = new WlanListItem(); + QListWidgetItem *p_listWidgetItem = new QListWidgetItem(); + p_listWidgetItem->setFlags(p_listWidgetItem->flags() & (~Qt::ItemIsSelectable)); //设置不可被选中 + p_listWidgetItem->setSizeHint(QSize(wirelessListWidget->width(), p_wlanItem->height())); + wirelessListWidget->addItem(p_listWidgetItem); + wirelessListWidget->setItemWidget(p_listWidgetItem, p_wlanItem); + + return p_listWidgetItem; +} + +QListWidgetItem *WlanPage::addNewItem(KyWirelessNetItem &wirelessNetItem, + QListWidget *wirelessListWidget) +{ + WlanListItem *p_wlanItem = new WlanListItem( + wirelessNetItem, + m_currentDevice, + m_connectResource->isApConnection(wirelessNetItem.m_connectUuid)); + connect(p_wlanItem, &WlanListItem::itemHeightChanged, this, &WlanPage::onItemHeightChanged); + + QListWidgetItem *p_listWidgetItem = new QListWidgetItem(); + p_listWidgetItem->setFlags(p_listWidgetItem->flags() & (~Qt::ItemIsSelectable)); + p_listWidgetItem->setSizeHint(QSize(wirelessListWidget->width(), p_wlanItem->height())); + wirelessListWidget->addItem(p_listWidgetItem); + wirelessListWidget->setItemWidget(p_listWidgetItem, p_wlanItem); + + return p_listWidgetItem; +} + +QListWidgetItem *WlanPage::insertNewItem(KyWirelessNetItem &wirelessNetItem, + QListWidget *wirelessListWidget, + int row) +{ + WlanListItem *p_wlanItem = new WlanListItem(wirelessNetItem, m_currentDevice); + connect(p_wlanItem, &WlanListItem::itemHeightChanged, this, &WlanPage::onItemHeightChanged); + + QListWidgetItem *p_listWidgetItem = new QListWidgetItem(); + p_listWidgetItem->setFlags(p_listWidgetItem->flags() & (~Qt::ItemIsSelectable)); + p_listWidgetItem->setSizeHint(QSize(wirelessListWidget->width(), p_wlanItem->height())); + wirelessListWidget->insertItem(row, p_listWidgetItem); + wirelessListWidget->setItemWidget(p_listWidgetItem, p_wlanItem); + + return p_listWidgetItem; +} + +QListWidgetItem *WlanPage::insertNewItemWithSort(KyWirelessNetItem &wirelessNetItem, + QListWidget *p_ListWidget) +{ + int row = 0; + + // qDebug()<< "insertNewItemWithSort" << wirelessNetItem.m_NetSsid + // <<"sort item config" << wirelessNetItem.m_isConfigured + // << "signal strength" << wirelessNetItem.m_signalStrength; + WlanListItem *p_sortWlanItem = new WlanListItem(wirelessNetItem, m_currentDevice); + connect(p_sortWlanItem, &WlanListItem::itemHeightChanged, this, &WlanPage::onItemHeightChanged); + + QListWidgetItem *p_sortListWidgetItem = new QListWidgetItem(); + p_sortListWidgetItem->setFlags(p_sortListWidgetItem->flags() & (~Qt::ItemIsSelectable)); + p_sortListWidgetItem->setSizeHint(QSize(p_ListWidget->width(), p_sortWlanItem->height())); + + // qDebug() << "insertNewItemWithSort, count" << p_ListWidget->count(); + for (row = 0; row < p_ListWidget->count() - 1; ++row) { + QListWidgetItem *p_listWidgetItem = p_ListWidget->item(row); + WlanListItem *p_wlanItem = (WlanListItem *)p_ListWidget->itemWidget(p_listWidgetItem); + + if (WMI_OB_NAME == p_wlanItem->objectName()) { + qDebug() << "insertNewItemWithSort" << "p_wlanItem is WlanMoreItem"; + continue; + } + + // qDebug()<< "insertNewItemWithSort" << p_wlanItem->getSsid() + // <<"item config" << p_wlanItem->isConfigured() + // << "signal strength" << p_wlanItem->getSignalStrength(); + + if (wirelessNetItem.m_isConfigured == p_wlanItem->isConfigured()) { + if (wirelessNetItem.m_signalStrength > p_wlanItem->getSignalStrength()) { + break; + } + } else { + if (wirelessNetItem.m_isConfigured) { + break; + } + } + } + + p_ListWidget->insertItem(row, p_sortListWidgetItem); + p_ListWidget->setItemWidget(p_sortListWidgetItem, p_sortWlanItem); + + //qDebug()<< "insertNewItemWithSort" << "insert sort item finished. row" << row; + return p_sortListWidgetItem; +} + +void WlanPage::clearWirelessNetItemMap(QMap &wirelessNetItem, + QListWidget *wirelessListWidget) +{ + QMap::iterator iter; + + iter = wirelessNetItem.begin(); + while (iter != wirelessNetItem.end()) { + QListWidgetItem *p_listWidgetItem = iter.value(); + if (p_listWidgetItem == m_hiddenItem) { + continue; + } + + WlanListItem *p_wlanItem = (WlanListItem *)wirelessListWidget->itemWidget(p_listWidgetItem); + wirelessListWidget->removeItemWidget(p_listWidgetItem); + + delete p_wlanItem; + p_wlanItem = nullptr; + + delete p_listWidgetItem; + p_listWidgetItem = nullptr; + + iter = wirelessNetItem.erase(iter); + } + + return; +} + +void WlanPage::deleteWirelessItemFormMap(QMap &wirelessNetItemMap, + QListWidget *wirelessListWidget, QString ssid) +{ + QListWidgetItem *p_listWidgetItem = wirelessNetItemMap.value(ssid); + if (nullptr == p_listWidgetItem) { + qWarning()<< LOG_FLAG <<"wireless item is not exsit, it's ssid is " << ssid; + return; + } + + WlanListItem *p_wlanItem = (WlanListItem *)wirelessListWidget->itemWidget(p_listWidgetItem); + if (nullptr == p_wlanItem) { + qWarning() << LOG_FLAG << "p_wlanItem is null"; + return; + } + + wirelessNetItemMap.remove(ssid); + + wirelessListWidget->takeItem(wirelessListWidget->row(p_listWidgetItem)); + + delete p_wlanItem; + p_wlanItem = nullptr; + + delete p_listWidgetItem; + p_listWidgetItem = nullptr; + + if (m_inactivatedNetListWidget->count() < MAX_ITEMS) { + m_inactivatedNetListWidget->setFixedWidth(MIN_WIDTH); + } + return; +} + +void WlanPage::updateWlanItemState(QListWidget *p_wirelessListWidget, + QListWidgetItem *p_listWidgetItem, + ConnectState state) +{ + WlanListItem *p_wlanItem = nullptr; + p_wlanItem = (WlanListItem *)p_wirelessListWidget->itemWidget(p_listWidgetItem); + if (nullptr != p_wlanItem) { + p_wlanItem->updateConnectState(state); + } + + return; +} + +void WlanPage::constructActivateConnectionArea() +{ + int height = 0; + clearWirelessNetItemMap(m_activateConnectionItemMap, m_activatedNetListWidget); + + if (!m_currentDevice.isEmpty()) { + KyWirelessNetItem wirelessNetItem; + bool ret = m_wirelessNetResource->getActiveWirelessNetItem(m_currentDevice, wirelessNetItem); + if (ret == true) { + QListWidgetItem *p_listWidgetItem = addNewItem(wirelessNetItem, m_activatedNetListWidget); + m_activateConnectionItemMap.insert(wirelessNetItem.m_NetSsid, p_listWidgetItem); + updateWlanItemState(m_activatedNetListWidget, p_listWidgetItem, Activated); + + height += p_listWidgetItem->sizeHint().height(); + } + } + + if (height == 0) { + QListWidgetItem *p_listWidgetItem = addEmptyItem(m_activatedNetListWidget); + m_activateConnectionItemMap.insert(EMPTY_SSID, p_listWidgetItem); + + height += p_listWidgetItem->sizeHint().height(); + } + + m_activatedNetListWidget->setFixedHeight(height); + + return; +} + +void WlanPage::constructWirelessNetArea() +{ + qDebug() << "[WlanPage] Started loading wireless net list!" + << QDateTime::currentDateTime().toString("hh:mm:ss.zzzz"); + + clearWirelessNetItemMap(m_wirelessNetItemMap, m_inactivatedNetListWidget); + m_expandedItem = nullptr; + + QList wirelessNetItemList; + if (!m_wirelessNetResource->getDeviceWifiNetwork(m_currentDevice, wirelessNetItemList)) { + qWarning()<<"[WlanPage] get wireless net item list failed."; + return; + } + + QString activateSsid = m_activateConnectionItemMap.firstKey(); + + foreach (auto wirelessNetItem, wirelessNetItemList) { + if (wirelessNetItem.m_NetSsid == activateSsid) { + continue; + } + + QListWidgetItem *p_listWidgetItem = addNewItem(wirelessNetItem, m_inactivatedNetListWidget); + m_wirelessNetItemMap.insert(wirelessNetItem.m_NetSsid, p_listWidgetItem); + updateWlanItemState(m_inactivatedNetListWidget, p_listWidgetItem, Deactivated); + } + + addWlanMoreItem(); + + qDebug() << "[WlanPage] Stopped loading wireless net list! time=" + << QDateTime::currentDateTime().toString("hh:mm:ss.zzzz"); + if (m_inactivatedNetListWidget->count() < MAX_ITEMS) { + m_inactivatedNetListWidget->setFixedWidth(MIN_WIDTH); + } else { + m_inactivatedNetListWidget->setFixedWidth(MAX_WIDTH); + } + return; +} + +void WlanPage::initWlanArea() +{ + if (m_wlanSwitchEnable) { + m_activatedNetFrame->show(); + m_activatedNetDivider->show(); + constructActivateConnectionArea(); + + m_inactivatedNetFrame->show(); + constructWirelessNetArea(); + } else { + m_activatedNetFrame->hide(); + m_activatedNetDivider->hide(); + + m_inactivatedNetFrame->hide(); + } + + return; +} + +void WlanPage::onWlanAdded(QString interface, KyWirelessNetItem &item) +{ + //for dbus + QStringList info; + info << item.m_NetSsid + << QString::number(item.m_signalStrength) + << item.m_secuType + << (m_connectResource->isApConnection(item.m_connectUuid) ? IsApConnection : NotApConnection); + emit wlanAdd(interface, info); + + if (interface != m_currentDevice) { + qDebug() << "[WlanPage] wlan add interface not equal defaultdevice"; + return; + } + + if (m_wirelessNetItemMap.contains(item.m_NetSsid)) { + return; + } + + qDebug() << "[WlanPage] A Wlan Added! interface = " + << interface << "; ssid = " << item.m_NetSsid << Q_FUNC_INFO <<__LINE__; + + QListWidgetItem *p_listWidgetItem = insertNewItemWithSort(item, m_inactivatedNetListWidget); + m_wirelessNetItemMap.insert(item.m_NetSsid, p_listWidgetItem); + updateWlanItemState(m_inactivatedNetListWidget, p_listWidgetItem, Deactivated); + + addWlanMoreItem(); + if (m_inactivatedNetListWidget->count() >= MAX_ITEMS) { + m_inactivatedNetListWidget->setFixedWidth(MAX_WIDTH); + } + return; +} + +void WlanPage::onWlanRemoved(QString interface, QString ssid) +{ + emit wlanRemove(interface, ssid); + + if (interface != m_currentDevice) { + qDebug()<<"[WlanPage] the device is not current device," + <<"current device" << m_currentDevice + << "remove wlan device" << interface; + return; + } + + if (!m_wirelessNetItemMap.contains(ssid) && !m_activateConnectionItemMap.contains(ssid)) { + return; + } + + if (m_expandedItem == m_wirelessNetItemMap.value(ssid)) { + m_expandedItem = nullptr; + } + + qDebug() << "[WlanPage] A Wlan Removed! interface = " << interface + << "; ssid = " << ssid << Q_FUNC_INFO <<__LINE__; + + + if (m_wirelessNetItemMap.contains(ssid)) { + deleteWirelessItemFormMap(m_wirelessNetItemMap, + m_inactivatedNetListWidget, ssid); + } else { + deleteWirelessItemFormMap(m_activateConnectionItemMap, + m_activatedNetListWidget, ssid); + showDesktopNotify(tr("WLAN Disconnected Successfully")); + + QListWidgetItem *p_listWidgetItem = addEmptyItem(m_activatedNetListWidget); + m_activateConnectionItemMap.insert(EMPTY_SSID, p_listWidgetItem); + } + + return; +} + +void WlanPage::updateWlanListItem(QString ssid) +{ + KyWirelessNetItem wirelessNetItem; + + qDebug() << LOG_FLAG << "update wlan list item " << ssid; + + bool ret = m_wirelessNetResource->getWifiNetwork(m_currentDevice, ssid, wirelessNetItem); + if (ret) { + QListWidgetItem *p_listWidgetItem = m_wirelessNetItemMap.value(ssid); + if (p_listWidgetItem) { + WlanListItem *p_wlanItem = (WlanListItem *)m_inactivatedNetListWidget->itemWidget(p_listWidgetItem); + p_wlanItem->updateWirelessNetItem(wirelessNetItem); + p_wlanItem->updateConnectState(Deactivated); + emit this->wlanConnectChanged(Deactivated); + } + } + + return; +} + +void WlanPage::onConnectionAdd(QString deviceName, QString ssid) +{ + qDebug() << LOG_FLAG << "one connection is added, it's ssid " << ssid << "device name"<< deviceName; + + if (deviceName == m_currentDevice) { + updateWlanListItem(ssid); + } + + return; +} + +void WlanPage::onConnectionRemove(QString deviceName, QString ssid) +{ + qDebug() << LOG_FLAG << "one connection is removed, it's ssid " << ssid << "device name"<< deviceName; + if (deviceName == m_currentDevice) { + if (m_activateConnectionItemMap.contains(ssid)) { + updateWirelessNetArea(nullptr, ssid, deviceName); + } + updateWlanListItem(ssid); + } + + return; +} + +void WlanPage::onSecurityTypeChange(QString devName, QString ssid, QString secuType) +{ + QListWidgetItem *p_listWidgetItem = nullptr; + WlanListItem *p_wlanItem = nullptr; + + qDebug()<< LOG_FLAG << "security type is chenged"; + + if (m_wirelessNetItemMap.contains(ssid)) { + p_listWidgetItem = m_wirelessNetItemMap.value(ssid); + p_wlanItem = (WlanListItem*)m_inactivatedNetListWidget->itemWidget(p_listWidgetItem); + } else if (m_activateConnectionItemMap.contains(ssid)) { + p_listWidgetItem = m_activateConnectionItemMap.value(ssid); + p_wlanItem = (WlanListItem*)m_activatedNetListWidget->itemWidget(p_listWidgetItem); + } + + if (nullptr != p_wlanItem) { + p_wlanItem->updateWirelessNetSecurity(ssid, secuType); + } + + emit secuTypeChange(devName, ssid, secuType); + + return; +} + + +void WlanPage::addDeviceToCombox(QString deviceName) +{ + disconnect(m_deviceComboBox, QOverload::of(&QComboBox::currentIndexChanged), + this, &WlanPage::onDeviceComboxIndexChanged); + if (m_wlanSwitchEnable) { + if (m_currentDevice.isEmpty()){ + m_deviceFrame->hide(); + m_currentDevice = deviceName; + setDefaultDevice(WIRELESS, m_currentDevice); + } else if (m_deviceComboBox->count() == 0) { + m_deviceComboBox->addItem(m_currentDevice); + m_deviceComboBox->addItem(deviceName); + m_deviceFrame->show(); + m_deviceComboBox->show(); + m_tipsLabel->hide(); + } else { + m_deviceComboBox->addItem(deviceName); + } + } + + connect(m_deviceComboBox, QOverload::of(&QComboBox::currentIndexChanged), + this, &WlanPage::onDeviceComboxIndexChanged); + return; +} + +void WlanPage::onDeviceAdd(QString deviceName, NetworkManager::Device::Type deviceType) +{ + qDebug() << LOG_FLAG << "currentDevice" << m_currentDevice << "deviceAdd" << deviceName; + if (deviceType != NetworkManager::Device::Type::Wifi) { + return; + } + + if (m_devList.contains(deviceName)) { + return; + } + + if (m_devList.isEmpty()) { + m_wlanSwitchEnable = m_switchGsettings->get(WIRELESS_SWITCH).toBool(); + m_netSwitch->setEnabled(true); + m_netSwitch->setSwitchStatus(m_wlanSwitchEnable); + } + + m_devList << deviceName; + addDeviceToCombox(deviceName); + if (m_currentDevice == deviceName) { + initWlanArea(); + } + + emit deviceStatusChanged(); + + return; +} + +void WlanPage::deleteDeviceFromCombox(QString deviceName) +{ + disconnect(m_deviceComboBox, QOverload::of(&QComboBox::currentIndexChanged), + this, &WlanPage::onDeviceComboxIndexChanged); + + if (m_wlanSwitchEnable) { + if (0 == m_devList.count()) { + m_deviceFrame->hide(); + //m_tipsLabel->show(); + //m_deviceComboBox->hide(); + m_currentDevice = ""; + setDefaultDevice(WIRELESS, m_currentDevice); + } else if (1 == m_devList.count()) { + m_deviceFrame->hide(); + m_deviceComboBox->clear(); + m_currentDevice = m_devList.at(0); + setDefaultDevice(WIRELESS, m_currentDevice); + } else { + int index = m_deviceComboBox->findData(deviceName); + if (-1 != index) { + m_deviceComboBox->removeItem(index); + m_currentDevice = m_deviceComboBox->currentText(); + setDefaultDevice(WIRELESS, m_currentDevice); + } + } + } + + connect(m_deviceComboBox, QOverload::of(&QComboBox::currentIndexChanged), + this, &WlanPage::onDeviceComboxIndexChanged); + return; +} + +void WlanPage::onDeviceRemove(QString deviceName) +{ + if (!m_devList.contains(deviceName)) { + return; + } + + qDebug() << "deviceRemove" << deviceName; + + QString originalDeviceName = m_currentDevice; + + m_devList.removeOne(deviceName); + deleteDeviceFromCombox(deviceName); + + if (m_devList.isEmpty()) { + m_wlanSwitchEnable = false; + m_netSwitch->setSwitchStatus(m_wlanSwitchEnable); + m_netSwitch->setEnabled(false); + } + + if (originalDeviceName == deviceName) { + initWlanArea(); + } + + emit deviceStatusChanged(); +} + +void WlanPage::updateDeviceForCombox(QString oldDeviceName, QString newDeviceName) +{ + if (m_currentDevice == oldDeviceName) { + m_currentDevice = newDeviceName; + setDefaultDevice(WIRELESS, m_currentDevice); + } + + int index = m_deviceComboBox->findText(oldDeviceName); + if (index != -1) { + m_deviceComboBox->setItemText(index, newDeviceName); + } + + return; +} + +void WlanPage::onDeviceNameUpdate(QString oldName, QString newName) +{ + if (!m_devList.contains(oldName)) { + return; + } + + qDebug()<<"[WlanPage] update device name, old name" + << oldName << "new Name" << newName; + + m_devList.removeOne(oldName); + m_devList.append(newName); + + QString originalDeviceName = m_currentDevice; + + updateDeviceForCombox(oldName, newName); + if (originalDeviceName != m_currentDevice) { + initWlanArea(); + } + + emit deviceNameChanged(oldName, newName, WIRELESS); +} + +void WlanPage::sendApStateChangeSignal(QString uuid, + QString ssid, + QString deviceName, + NetworkManager::ActiveConnection::State state) +{ + bool ret = false; + ret = m_connectResource->isApConnection(uuid); + if (!ret) { + return; + } + + if (state == NetworkManager::ActiveConnection::State::Deactivated) { + qDebug() << "[WlanPage] hotspot Deactivated"; + emit hotspotDeactivated(deviceName, ssid); + } else if (state == NetworkManager::ActiveConnection::State::Activated) { + qDebug() << "[WlanPage] hotspot activated"; + emit hotspotActivated(deviceName, ssid, uuid); + } + + return; +} + +void WlanPage::wlanShowNotify(QString ssid, NetworkManager::ActiveConnection::State state, + NetworkManager::ActiveConnection::Reason reason) +{ + if (state == NetworkManager::ActiveConnection::State::Deactivated) { + showDesktopNotify(tr("WLAN Disconnected Successfully")); + qDebug() << "[WlanPage] wlan disconnected successfully" << Q_FUNC_INFO <<__LINE__; + } else if (state == NetworkManager::ActiveConnection::State::Activated) { + qDebug() << "[WlanPage] wlan connected successfully" << Q_FUNC_INFO <<__LINE__; + this->showDesktopNotify(tr("WLAN Connected Successfully")); + } + + return; +} + +void WlanPage::updateActivatedArea(QString uuid, QString ssid, QString devName) +{ + if (m_activateConnectionItemMap.contains(ssid)) { + return; + } + + if (m_expandedItem == m_wirelessNetItemMap.value(ssid)) { + m_expandedItem = nullptr; + } + deleteWirelessItemFormMap(m_wirelessNetItemMap, + m_inactivatedNetListWidget, ssid); + + KyWirelessNetItem wirelessNetItem; + bool ret = m_wirelessNetResource->getWifiNetwork(devName, ssid, wirelessNetItem); + if (!ret) { + qWarning()<<"[WlanPage] get wireless item failed, when update activated connection area."; + return; + } + + deleteWirelessItemFormMap(m_activateConnectionItemMap, m_activatedNetListWidget, EMPTY_SSID); + QListWidgetItem *p_listWidgetItem = addNewItem(wirelessNetItem, m_activatedNetListWidget); + m_activateConnectionItemMap.insert(wirelessNetItem.m_NetSsid, p_listWidgetItem); + + m_activatedNetListWidget->setFixedHeight(p_listWidgetItem->sizeHint().height()); + if (m_inactivatedNetListWidget->count() < MAX_ITEMS) { + m_inactivatedNetListWidget->setFixedWidth(MIN_WIDTH); + } + return; +} + +void WlanPage::updateWirelessNetArea(QString uuid, QString ssid, QString devName) +{ + if(m_wirelessNetItemMap.contains(ssid)) { + return; + } + + if (m_activateConnectionItemMap.contains(ssid)) { + deleteWirelessItemFormMap(m_activateConnectionItemMap, m_activatedNetListWidget, ssid); + QListWidgetItem *p_activeListWidgetItem = addEmptyItem(m_activatedNetListWidget); + m_activateConnectionItemMap.insert(EMPTY_SSID, p_activeListWidgetItem); + m_activatedNetListWidget->setFixedHeight(p_activeListWidgetItem->sizeHint().height()); + } else { + qDebug() << LOG_FLAG << ssid << "is not in activeconnection map"; + } + + KyWirelessNetItem wirelessNetItem; + bool ret = m_wirelessNetResource->getWifiNetwork(devName, ssid, wirelessNetItem); + if (!ret) { + qWarning()<<"[WlanPage] get wireless item failed, when update wireless area."; + return; + } + + QListWidgetItem *p_listWidgetItem = insertNewItemWithSort(wirelessNetItem, m_inactivatedNetListWidget); + m_wirelessNetItemMap.insert(wirelessNetItem.m_NetSsid, p_listWidgetItem); + + // 更新‘更多’条目,以保证其处于listwidget的最底部 + addWlanMoreItem(); + if (m_inactivatedNetListWidget->count() < MAX_ITEMS) { + m_inactivatedNetListWidget->setFixedWidth(MIN_WIDTH); + } else { + m_inactivatedNetListWidget->setFixedWidth(MAX_WIDTH); + } + return; +} + +void WlanPage::onConnectionStateChanged(QString uuid, + NetworkManager::ActiveConnection::State state, + NetworkManager::ActiveConnection::Reason reason) +{ + QString devName, ssid; + m_wirelessNetResource->getSsidByUuid(uuid, ssid); + m_wirelessNetResource->getDeviceByUuid(uuid, devName); + + qDebug()<< LOG_FLAG << "emit wlanActiveConnectionStateChanged" << devName << ssid << state; + emit wlanActiveConnectionStateChanged(devName, ssid, uuid, state); + + if (ssid.isEmpty() || devName.isEmpty()) { + qDebug()<< LOG_FLAG << "ssid or devicename is empty" + << "devicename"<< devName <<"ssid"<isWirelessConnection(uuid)) { + qDebug()<< LOG_FLAG << "it is not wireless connection" << uuid; + return; + } + + emit this->wlanConnectChanged(state); + + if (m_connectResource->isApConnection(uuid)) { + sendApStateChangeSignal(uuid, ssid, devName, state); + } else { + if (state == NetworkManager::ActiveConnection::State::Deactivated && + !m_activateConnectionItemMap.contains(ssid)) { + qDebug() << "wlan remove before deactivated"; + } else { + wlanShowNotify(ssid, state, reason); + } + } + + if (devName != m_currentDevice) { + return; + } + + qDebug()<< "[WlanPage] wlan state changed, ssid = " << ssid + << "; state = " << state << "; reason = " << reason << Q_FUNC_INFO <<__LINE__; + if (state == NetworkManager::ActiveConnection::State::Activated) { + m_updateStrength = true; + updateActivatedArea(uuid, ssid, devName); + if (m_activateConnectionItemMap.contains(ssid)) { + QListWidgetItem *p_listWidgetItem = m_activateConnectionItemMap.value(ssid); + updateWlanItemState(m_activatedNetListWidget, p_listWidgetItem, Activated); + } + } else if (state == NetworkManager::ActiveConnection::State::Deactivated) { + m_updateStrength = true; + updateWirelessNetArea(uuid, ssid, devName); + if (m_wirelessNetItemMap.contains(ssid)) { + QListWidgetItem *p_listWidgetItem = m_wirelessNetItemMap.value(ssid); + updateWlanItemState(m_inactivatedNetListWidget, p_listWidgetItem, Deactivated); + } + } else if (state == NetworkManager::ActiveConnection::State::Deactivating){ + m_updateStrength = false; + if (m_activateConnectionItemMap.contains(ssid)) { + QListWidgetItem *p_listWidgetItem = m_activateConnectionItemMap.value(ssid); + updateWlanItemState(m_activatedNetListWidget, p_listWidgetItem, Deactivating); + } + } else if (state == NetworkManager::ActiveConnection::State::Activating) { + m_updateStrength = false; + if (m_wirelessNetItemMap.contains(ssid)) { + QListWidgetItem *p_listWidgetItem = m_wirelessNetItemMap.value(ssid); + updateWlanItemState(m_inactivatedNetListWidget, p_listWidgetItem, Activating); + } + } + return; +} + +void WlanPage::onItemHeightChanged(const bool isExpanded, const QString &ssid) +{ + if (!m_wirelessNetItemMap.contains(ssid)) { + return; + } + + QListWidgetItem *p_listWidgetItem = m_wirelessNetItemMap.value(ssid); + + qDebug()<sizeHint().height(); + int width = p_listWidgetItem->sizeHint().width(); + + if (isExpanded) { + if (m_expandedItem != p_listWidgetItem) { + qDebug()<setSizeHint(expandedSize); + } + m_inactivatedNetListWidget->scrollToItem(p_listWidgetItem, QAbstractItemView::QAbstractItemView::EnsureVisible); + } else { + m_expandedItem = nullptr; + + if (height > NORMAL_HEIGHT) { + qDebug()<setSizeHint(normalSize); + } + } + + return; +} + +void WlanPage::onDeviceComboxIndexChanged(int currentIndex) +{ + qDebug() << "onDeviceComboxIndexChanged"; + if (!m_deviceComboBox || currentIndex < 0) { + return; + } + + m_currentDevice = m_deviceComboBox->itemText(currentIndex); + setDefaultDevice(WIRELESS, m_currentDevice); + + initWlanArea(); + + return; +} + +//申请触发扫描,初始化执行&定时执行 +void WlanPage::requestScan() +{ + if (!m_wirelessConnectOpreation) { + qWarning() << "[WlanPage]Scan failed! m_wirelessConnectOpreation is nullptr!" << Q_FUNC_INFO << __LINE__; + return; + } + + m_wirelessConnectOpreation->requestWirelessScan(); + + return; +} + +void WlanPage::onHiddenWlanClicked() +{ + qDebug() << "[wlanPage] AddHideWifi Clicked! " << Q_FUNC_INFO << __LINE__ ; + NetDetail *netDetail = new NetDetail(m_currentDevice, "", "", false, true, true, this); + netDetail->show(); +} + +void WlanPage::showControlCenter() +{ + qDebug() << LOG_FLAG <<"show control center"; + + QProcess process; + process.startDetached("ukui-control-center -m wlanconnect"); + + return; +} + +void WlanPage::onWifiEnabledChanged(bool isWifiOn) +{ + //监听外部命令导致wifi状态变化,更新界面 + qDebug() << "[WlanPage] onWifiEnabledChanged wifi state" << isWifiOn; + + //应该先检测是否有无线网卡可用,才改变开关状态 + if (m_devList.isEmpty()) { + qDebug() << "[WLanPage] have no device to use " << Q_FUNC_INFO << __LINE__; + return; + } + + if (m_wlanSwitchEnable == isWifiOn) { + return; + } else { + if (!m_netSwitch->getEnabled()) { + m_netSwitch->setEnabled(true); + } + m_switchGsettings->set(WIRELESS_SWITCH, isWifiOn); + } + + return; +} + +void WlanPage::refreshActiveConnectionIcon(QString ssid, const int &signal) +{ + QListWidgetItem *p_listWidgetItem = m_activateConnectionItemMap.value(ssid); + if (p_listWidgetItem) { + WlanListItem *p_wlanItem = (WlanListItem *)m_activatedNetListWidget->itemWidget(p_listWidgetItem); + if (nullptr != p_wlanItem) { + p_wlanItem->setSignalStrength(signal); + return; + } + } +} + +void WlanPage::onRefreshIconTimer() +{ + if (!m_updateStrength) { + return; + } + + emit timeToUpdate(); + + if(!this->isVisible()) { + return; + } + //qDebug() << "onRefreshIconTimer"; + + if (m_expandedItem) { + qDebug()<< LOG_FLAG << "Has expanded item and forbid refresh wifi strength" << Q_FUNC_INFO << __LINE__; + return; + } + + QList wlanList; + if (!m_wirelessNetResource->getDeviceWifiNetwork(m_currentDevice, wlanList)) { + return; + } + + + QString activateSsid = m_activateConnectionItemMap.firstKey(); + int sortRow = 0; + for (int index = 0; index < wlanList.length(); index++) { + KyWirelessNetItem sortItem = wlanList.at(index); + QString sortSsid = sortItem.m_NetSsid; //应该在第currentRow行的新的WiFi名称 + //qDebug()<< LOG_FLAG << "sort ssid"<< sortSsid << "active ssid" << activateSsid << "sort row"<< sortRow; + if (sortSsid == activateSsid) { //排除已连接WiFi + refreshActiveConnectionIcon(activateSsid, sortItem.m_signalStrength); + continue; + } + + QListWidgetItem *p_listWidgetItem = m_inactivatedNetListWidget->item(sortRow); + if (p_listWidgetItem) { + WlanListItem *p_wlanItem = (WlanListItem *)m_inactivatedNetListWidget->itemWidget(p_listWidgetItem); + + if (nullptr == p_wlanItem) { + qDebug() << LOG_FLAG << "p_wlanItem is null continue"; + continue;//暂时先保持continue,后续讨论是否使用break直接跳出循环 + } + + // 该item是‘更多’条目,不需要更新 + if (WMI_OB_NAME == p_wlanItem->objectName()) { + qDebug() << LOG_FLAG << "p_wlanItem is WlanMoreItem"; + continue; + } + + //qDebug()<< LOG_FLAG << "row" << sortRow << "item ssid" << p_wlanItem->getSsid(); + if (sortSsid == p_wlanItem->getSsid()) { + // qDebug()<< LOG_FLAG << "sort wlan set signal strength." << Q_FUNC_INFO << __LINE__; + p_wlanItem->setSignalStrength(sortItem.m_signalStrength); + sortRow++; + continue; + } + + QListWidgetItem *p_sortListWidgetItem = m_wirelessNetItemMap.value(sortSsid); + if (p_sortListWidgetItem) { + WlanListItem *p_wlanItem = (WlanListItem *)m_inactivatedNetListWidget->itemWidget(p_listWidgetItem); + if (p_wlanItem == nullptr) { + continue; + } + + if (Deactivated != p_wlanItem->getConnectionState()) { + continue; + } + // qDebug()<< LOG_FLAG << "sort wlan update position." << sortSsid << Q_FUNC_INFO << __LINE__; + int takeRow = m_inactivatedNetListWidget->row(p_sortListWidgetItem); + m_inactivatedNetListWidget->takeItem(takeRow); + + WlanListItem *p_sortWlanItem = new WlanListItem(sortItem, m_currentDevice); + connect(p_sortWlanItem, &WlanListItem::itemHeightChanged, this, &WlanPage::onItemHeightChanged); + m_inactivatedNetListWidget->insertItem(sortRow, p_sortListWidgetItem); + m_inactivatedNetListWidget->setItemWidget(p_sortListWidgetItem, p_sortWlanItem); + updateWlanItemState(m_inactivatedNetListWidget, p_sortListWidgetItem, Deactivated); + sortRow++; + continue; + } + } + + //qDebug()<< LOG_FLAG << "sort wlan add new item." << Q_FUNC_INFO << __LINE__; + QListWidgetItem *p_newListWidgetItem = insertNewItem(sortItem, m_inactivatedNetListWidget, sortRow); + m_wirelessNetItemMap.insert(sortItem.m_NetSsid, p_newListWidgetItem); + updateWlanItemState(m_inactivatedNetListWidget, p_listWidgetItem, Deactivated); + + sortRow++; + } + + // qDebug()<< LOG_FLAG << "sort wlan finished." << Q_FUNC_INFO << __LINE__; + + return; +} + +//for dbus +void WlanPage::getWirelessList(QMap > &map) +{ + QMap actMap; + m_wirelessNetResource->getWirelessActiveConnection(NetworkManager::ActiveConnection::State::Activated, actMap); + + QMap > wlanMap; + if (!m_wirelessNetResource->getAllDeviceWifiNetwork(wlanMap)) { + return; + } + + QMap >::iterator iter = wlanMap.begin(); + while (iter != wlanMap.end()) { + QVector vector; + QString activeSsid ; + //先是已连接 + if (actMap.contains(iter.key())) { + qDebug() << "find " <getSsidByUuid(actMap[iter.key()].at(0), ssid); + if (m_wirelessNetResource->getWifiNetwork(iter.key(), ssid, data)) { + vector.append(QStringList() << data.m_NetSsid + << QString::number(data.m_signalStrength) + << data.m_secuType + << data.m_connectUuid + << (m_connectResource->isApConnection(data.m_connectUuid) ? IsApConnection : NotApConnection)); + activeSsid = data.m_NetSsid; + } else { + vector.append(QStringList("--")); + } + } else { + vector.append(QStringList("--")); + } + //未连接 + foreach (auto itemData, iter.value()) { + if (itemData.m_NetSsid == activeSsid) { + continue; + } + vector.append(QStringList()<isApConnection(itemData.m_connectUuid) ? IsApConnection : NotApConnection)); + } + + map.insert(iter.key(), vector); + iter++; + } + + return; +} + +//开启热点 +void WlanPage::activeWirelessAp(const QString apName, const QString apPassword, const QString wirelessBand, const QString apDevice) +{ + QString uuid(""); + QList apConnectItemList; + m_connectResource->getApConnections(apConnectItemList); + if (!apConnectItemList.isEmpty()) { + uuid = apConnectItemList.at(0)->m_connectUuid; + } + + m_wirelessConnectOpreation->activeWirelessAp(uuid, apName, apPassword, apDevice, wirelessBand); +} + +//断开热点 +void WlanPage::deactiveWirelessAp(const QString apName, const QString uuid) +{ + if (!uuid.isEmpty()) { + m_wirelessConnectOpreation->deactiveWirelessAp(apName, uuid); + } +} + +void WlanPage::getStoredApInfo(QStringList &list) +{ + list.clear(); + QList apConnectItemList; + m_connectResource->getApConnections(apConnectItemList); + if (!apConnectItemList.isEmpty()) { + list << apConnectItemList.at(0)->m_connectSsid; + list << apConnectItemList.at(0)->m_password; + list << apConnectItemList.at(0)->m_ifaceName; + list << (apConnectItemList.at(0)->m_isActivated? "true":"false"); + list << apConnectItemList.at(0)->m_connectUuid; + list << apConnectItemList.at(0)->m_band; + } +} + +void WlanPage::getApInfoBySsid(QString devName, QString ssid, QStringList &list) +{ + list.clear(); + QList apConnectItemList; + m_connectResource->getApConnections(apConnectItemList); + for (int i = 0; i < apConnectItemList.size(); i++) { + if (apConnectItemList.at(i)->m_connectSsid == ssid + && apConnectItemList.at(i)->m_ifaceName == devName) { + list << apConnectItemList.at(i)->m_password; + list << apConnectItemList.at(i)->m_band; + } + } + + return; +} + +void WlanPage::activateWirelessConnection(const QString& devName, const QString& ssid) +{ + KyWirelessNetItem wirelessNetItem; + if (!m_wirelessNetResource->getWifiNetwork(devName, ssid, wirelessNetItem)) { + qDebug() << "[WlanPage] no such wifi " << ssid << " in " << devName; + return; + } + + if (devName != m_currentDevice) { + int index = m_deviceComboBox->findText(devName); + if (index >= 0) { + m_deviceComboBox->setCurrentIndex(index); + } else { + qDebug() << "[WlanPage]activateWirelessConnection no such " << devName; + return; + } + } + + QListWidgetItem *p_listWidgetItem = nullptr; + WlanListItem *p_wlanItem = nullptr; + + if (m_wirelessNetItemMap.contains(ssid)) { + p_listWidgetItem = m_wirelessNetItemMap.value(ssid); + p_wlanItem = (WlanListItem*)m_inactivatedNetListWidget->itemWidget(p_listWidgetItem); + + m_inactivatedNetListWidget->scrollToItem(p_listWidgetItem, QAbstractItemView::EnsureVisible); + + + QMouseEvent *event = new QMouseEvent(QEvent::MouseButtonPress, QPoint(0,0), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + QApplication::postEvent(p_wlanItem, event); + emit showMainWindow(WLAN_PAGE_INDEX); + } else { + qDebug() << "[WlanPage]activateWirelessConnection no such " << ssid << "in" << devName; + } + return; +} + +void WlanPage::deactivateWirelessConnection(const QString& devName, const QString& ssid) +{ + KyWirelessNetItem wirelessNetItem; + if (!m_wirelessNetResource->getWifiNetwork(devName, ssid, wirelessNetItem)) { + qDebug() << "[WlanPage] no such wifi " << ssid << " in " << devName; + return; + } + + if (!m_connectResource->isActivatedConnection(wirelessNetItem.m_connectUuid)) { + qDebug()<<"[WlanPage]"<deActivateWirelessConnection(wirelessNetItem.m_connName, wirelessNetItem.m_connectUuid); + + return; +} + +void WlanPage::onMainWindowVisibleChanged(const bool &visible) +{ + qDebug() << "[WlanPage] Received signal of mainwindow visible changed. cur_state = " << visible << Q_FUNC_INFO << __LINE__; + if (visible) { + //打开页面时先触发一次扫描,然后定时扫描wifi热点和刷新icon + requestScan(); + m_scanTimer->start(AP_SCAN_INTERVAL); + onRefreshIconTimer(); +// m_refreshIconTimer->start(ICON_REFRESH_INTERVAL); + } else { + //界面关闭的时候,停止wifi扫描和刷新 + m_scanTimer->stop(); +// m_refreshIconTimer->stop(); + qDebug() << "wlanpage not visible"; + showNonePwd(); + } + + return; +} + +void WlanPage::onWlanPageVisibleChanged(int index) +{ + if (index == LAN_PAGE_INDEX) { + qDebug() << "wlanpage not visible"; + showNonePwd(); + } +} + +void WlanPage::showNonePwd() +{ + QMap::iterator iter; + for(iter=m_wirelessNetItemMap.begin();iter!= m_wirelessNetItemMap.end();iter++) + { + if(iter.value() != nullptr) { + QListWidgetItem *p_listWidgetItem = iter.value(); + WlanListItem *p_wlanItem = (WlanListItem*)m_inactivatedNetListWidget->itemWidget(p_listWidgetItem); + p_wlanItem->forgetPwd(); + p_wlanItem->setExpanded(false); + } + } + return; +} + +void WlanPage::showDetailPage(QString devName, QString ssid) +{ + KyWirelessNetItem wirelessNetItem; + if (!m_wirelessNetResource->getWifiNetwork(devName, ssid, wirelessNetItem)) { + qDebug()<<"[WlanPage] " << ssid << " is missing when showDetailPage"; + return; + } + + bool isActive = m_connectResource->isActivatedConnection(wirelessNetItem.m_connectUuid); + + NetDetail *netDetail = new NetDetail(devName, ssid, wirelessNetItem.m_connectUuid, isActive, true, !wirelessNetItem.m_isConfigured, this); + netDetail->show(); + + return; +} + +bool WlanPage::checkWlanStatus(NetworkManager::ActiveConnection::State state) +{ + if (m_activatedConnectResource->checkWirelessStatus(state)) { + return true; + } else { + return false; + } +} + +void WlanPage::setWirelessSwitchEnable(bool enable) +{ + qDebug() << "dbus setWirelessSwitchEnable = " << enable << __LINE__; + //应该先检测是否有无线网卡可用,才改变开关状态 + if (m_devList.isEmpty()) { + qDebug() << "have no device to use " << Q_FUNC_INFO << __LINE__; + //检测不到无线网卡不再触发click信号 + m_netSwitch->setSwitchStatus(false); + //m_netSwitch->setEnabled(false); + }else{ + m_wirelessConnectOpreation->setWirelessEnabled(enable); + if (!enable) { + m_netSwitch->setEnabled(false); + m_activatedNetFrame->hide(); + m_activatedNetDivider->hide(); + m_inactivatedNetFrame->hide(); + m_deviceFrame->hide(); + } + } +} + +void WlanPage::getWirelessDeviceCap(QMap &map) +{ + for (int i = 0; i < m_devList.size(); ++i) { + QString devName = m_devList.at(i); + map.insert(devName, m_netDeviceResource->getWirelessDeviceCapability(devName)); + } +} + +void WlanPage::getConnectivity(NetworkManager::Connectivity &connectivity) +{ + m_connectResource->getConnectivity(connectivity); +} + +/** + * @brief WlanPage::addWlanMoreItem + * 添加‘更多网络’的条目 + */ +void WlanPage::addWlanMoreItem() +{ + if (m_hiddenItem) { + m_inactivatedNetListWidget->takeItem(m_inactivatedNetListWidget->row(m_hiddenItem)); + delete m_hiddenItem; + m_hiddenItem = nullptr; + } + + if (m_hiddenWlanWidget) { +// disconnect(m_hiddenWlanWidget, &WlanMoreItem::hiddenWlanClicked, this, &WlanPage::onHiddenWlanClicked); + m_hiddenWlanWidget->setParent(nullptr); + delete m_hiddenWlanWidget; + m_hiddenWlanWidget = nullptr; + } + + m_hiddenWlanWidget = new WlanMoreItem(this); + connect(m_hiddenWlanWidget, &WlanMoreItem::hiddenWlanClicked, this, &WlanPage::onHiddenWlanClicked); + m_hiddenWlanWidget->setFixedHeight(NORMAL_HEIGHT); + + m_hiddenItem = new QListWidgetItem(m_inactivatedNetListWidget); + m_hiddenItem->setFlags(m_hiddenItem->flags() & (~Qt::ItemIsSelectable)); + m_hiddenItem->setSizeHint(QSize(m_inactivatedNetListWidget->width(), m_hiddenWlanWidget->height())); + m_inactivatedNetListWidget->addItem(m_hiddenItem); + m_inactivatedNetListWidget->setItemWidget(m_hiddenItem, m_hiddenWlanWidget); + return; +} diff --git a/src/frontend/tab-pages/wlanpage.h b/src/frontend/tab-pages/wlanpage.h new file mode 100644 index 00000000..270af216 --- /dev/null +++ b/src/frontend/tab-pages/wlanpage.h @@ -0,0 +1,186 @@ +#ifndef WLANPAGE_H +#define WLANPAGE_H + +#include "tabpage.h" +#include "kywirelessnetresource.h" +#include "kylinactiveconnectresource.h" +#include "kylinnetworkdeviceresource.h" +#include "kywirelessconnectoperation.h" +#include "wlanlistitem.h" +#include "wlanmoreitem.h" +#include "kylinconnectoperation.h" +#include +#include "netdetails/netdetail.h" +#include +#include "kylinactiveconnectresource.h" +#include "kywirelessnetresource.h" + +//#define SCROLLAREA_HEIGHT 150 +#define MORE_TEXT_MARGINS 16,0,0,0 +#define SCROLLAREA_HEIGHT 200 + +#define LAN_PAGE_INDEX 0 +#define WLAN_PAGE_INDEX 1 + +class WlanListItem; + +class WlanPage : public TabPage +{ + Q_OBJECT +public: + explicit WlanPage(QWidget *parent = nullptr); + ~WlanPage() = default; + + //for dbus + void getWirelessList(QMap > &map); + //开启热点 + void activeWirelessAp(const QString apName, const QString apPassword, const QString wirelessBand, const QString apDevice); + //断开热点 + void deactiveWirelessAp(const QString apName, const QString uuid); + //获取热点 + void getStoredApInfo(QStringList &list); + + void activateWirelessConnection(const QString& devName, const QString& ssid); + void deactivateWirelessConnection(const QString& devName, const QString& ssid); + + void showDetailPage(QString devName, QString uuid); + + bool checkWlanStatus(NetworkManager::ActiveConnection::State state); + + void getApInfoBySsid(QString devName, QString ssid, QStringList &list); + //无线总开关 + void setWirelessSwitchEnable(bool enable); + void getWirelessDeviceCap(QMap &map); + + void getConnectivity(NetworkManager::Connectivity &connectivity); + +signals: + void oneItemExpanded(const QString &ssid); + void wlanAdd(QString devName, QStringList info); + void wlanRemove(QString devName,QString ssid); + void wlanActiveConnectionStateChanged(QString interface, QString ssid, QString uuid, int status); + void hotspotDeactivated(QString devName, QString ssid); + void hotspotActivated(QString devName, QString ssid, QString uuid); + void signalStrengthChange(QString devName, QString ssid, int strength); + void secuTypeChange(QString devName, QString ssid, QString secuType); + void hiddenWlanClicked(); + void wlanConnectChanged(int state); + void timeToUpdate(); + + void showMainWindow(int type); + + void connectivityChanged(NetworkManager::Connectivity connectivity); + +public slots: + void onMainWindowVisibleChanged(const bool &visible); + void onSecurityTypeChange(QString devName, QString ssid, QString secuType); + void requestScan(); + void onWlanPageVisibleChanged(int index); + +private slots: + void onWlanAdded(QString interface, KyWirelessNetItem &item); + void onWlanRemoved(QString interface, QString ssid); + + void onConnectionAdd(QString deviceName, QString ssid); + void onConnectionRemove(QString deviceName, QString ssid); + + void onDeviceAdd(QString deviceName, NetworkManager::Device::Type deviceType); + void onDeviceRemove(QString deviceName); + void onDeviceNameUpdate(QString oldName, QString newName); + + void onConnectionStateChanged(QString uuid, + NetworkManager::ActiveConnection::State state, + NetworkManager::ActiveConnection::Reason reason); + void onItemHeightChanged(const bool isExpanded, const QString &ssid); + + void onWlanSwitchClicked(); + void onWlanSwithGsettingsChanged(const QString &key); + + void onDeviceComboxIndexChanged(int currentIndex); + void onHiddenWlanClicked(); + void showControlCenter(); + void onWifiEnabledChanged(bool isWifiOn); + void onRefreshIconTimer(); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + //定时触发扫描的定时器 + void initTimer(); + void initWlanUI(); + void initConnections(); + void initDevice();//初始化默认设备 + void initDeviceCombox(); + void initWlanSwitchState(); + void initWlanArea(); + void addWlanMoreItem(); + + void showNonePwd(); + + QListWidgetItem *addEmptyItem(QListWidget *wirelessListWidget); + QListWidgetItem *addNewItem(KyWirelessNetItem &wirelessNetItem, + QListWidget *wirelessListWidget); + QListWidgetItem *insertNewItem(KyWirelessNetItem &wirelessNetItem, + QListWidget *wirelessListWidget, + int row); + QListWidgetItem *insertNewItemWithSort(KyWirelessNetItem &wirelessNetItem, + QListWidget *p_ListWidget); + + void clearWirelessNetItemMap(QMap &wirelessNetItem, + QListWidget *wirelessListWidget); + void deleteWirelessItemFormMap(QMap &wirelessNetItemMap, + QListWidget *wirelessListWidget, QString ssid); + + void updateWlanItemState(QListWidget *p_wirelessListWidget, + QListWidgetItem *p_listWidgetItem, + ConnectState state); + void updateWlanListItem(QString ssid); + void refreshActiveConnectionIcon(QString ssid, const int &signal); + + void constructWirelessNetArea(); + void constructActivateConnectionArea(); + + void updateActivatedArea(QString uuid, QString ssid, QString devName); + void updateWirelessNetArea(QString uuid, QString ssid, QString devName); + + void addDeviceToCombox(QString deviceName); + void deleteDeviceFromCombox(QString deviceName); + void updateDeviceForCombox(QString oldDeviceName, QString newDeviceName); + + void sendApStateChangeSignal(QString uuid, QString ssid, QString deviceName, + NetworkManager::ActiveConnection::State state); + void wlanShowNotify(QString ssid, NetworkManager::ActiveConnection::State state, + NetworkManager::ActiveConnection::Reason reason); + +private: + QMap m_wirelessNetItemMap; + QMap m_activateConnectionItemMap; + + QListWidgetItem *m_expandedItem = nullptr; + + WlanMoreItem * m_hiddenWlanWidget = nullptr; + QListWidgetItem *m_hiddenItem = nullptr; + + QListWidget * m_activatedNetListWidget = nullptr; + QListWidget * m_inactivatedNetListWidget = nullptr; + + QStringList m_devList; + QString m_currentDevice; + + KyWirelessNetResource *m_wirelessNetResource = nullptr; + KyActiveConnectResourse *m_activatedConnectResource = nullptr; + KyNetworkDeviceResourse *m_netDeviceResource = nullptr; + KyWirelessConnectOperation * m_wirelessConnectOpreation = nullptr; + KyConnectResourse * m_connectResource = nullptr; + + QGSettings *m_switchGsettings = nullptr; + bool m_wlanSwitchEnable = true; + + bool m_updateStrength = true; + + QTimer *m_scanTimer = nullptr; + QTimer *m_refreshIconTimer = nullptr; +}; + +#endif // WLANPAGE_H diff --git a/src/frontend/tools/divider.cpp b/src/frontend/tools/divider.cpp new file mode 100644 index 00000000..f82fba9a --- /dev/null +++ b/src/frontend/tools/divider.cpp @@ -0,0 +1,23 @@ +#include "divider.h" +#include +#include + +Divider::Divider(QWidget * parent) : QFrame(parent) +{ + this->setFixedHeight(1); +} + + + +void Divider::paintEvent(QPaintEvent * e) +{ + QPainter p(this); + QColor color = qApp->palette().color(QPalette::BrightText); + color.setAlphaF(0.08); + p.save(); + p.setBrush(color); + p.setPen(Qt::transparent); + p.drawRoundedRect(this->rect(), 6, 6); + p.restore(); + return QFrame::paintEvent(e); +} diff --git a/src/frontend/tools/divider.h b/src/frontend/tools/divider.h new file mode 100644 index 00000000..e22a6392 --- /dev/null +++ b/src/frontend/tools/divider.h @@ -0,0 +1,15 @@ +#ifndef DIVIDER_H +#define DIVIDER_H +#include + +class Divider : public QFrame +{ +public: + Divider(QWidget * parent = nullptr); + ~Divider() = default; + +protected: + void paintEvent(QPaintEvent *event); +}; + +#endif // DIVIDER_H diff --git a/src/frontend/tools/infobutton.cpp b/src/frontend/tools/infobutton.cpp new file mode 100644 index 00000000..0dd16cd8 --- /dev/null +++ b/src/frontend/tools/infobutton.cpp @@ -0,0 +1,93 @@ +#include "infobutton.h" +#include +#include +#include + +#define BUTTON_SIZE 36,36 +#define ICON_SIZE 16,16 +#define BACKGROUND_COLOR QColor(0,0,0,0) +#define FOREGROUND_COLOR_NORMAL qApp->palette().text().color() +#define FOREGROUND_COLOR_HOVER QColor(55,144,250,255) +#define FOREGROUND_COLOR_PRESS QColor(36,109,212,255) +#define OUTER_PATH 8,8,16,16 +#define INNER_PATH 9,9,14,14 +#define TEXT_POS 14,5,16,16,0 + +#define BUTTON_SIZE 36,36 + +InfoButton::InfoButton(QWidget *parent) : QPushButton(parent) +{ + this->setFixedSize(BUTTON_SIZE); + initUI(); + connect(qApp, &QApplication::paletteChanged, this, &InfoButton::onPaletteChanged); +} + +void InfoButton::initUI() +{ + this->setFixedSize(BUTTON_SIZE); + m_backgroundColor = BACKGROUND_COLOR; + m_foregroundColor = FOREGROUND_COLOR_NORMAL; +} + +void InfoButton::onPaletteChanged() +{ + m_foregroundColor = FOREGROUND_COLOR_NORMAL; + this->repaint(); +} + +void InfoButton::paintEvent(QPaintEvent *event) +{ + QPalette pal = this->palette(); + pal.setColor(QPalette::Base, m_backgroundColor); + pal.setColor(QPalette::Text, m_foregroundColor); + + QPainterPath cPath; + cPath.addRect(0, 0, ICON_SIZE); + cPath.addEllipse(0, 0, ICON_SIZE); + + QPainterPath outerPath; + outerPath.addEllipse(OUTER_PATH); + + QPainterPath innerPath; + innerPath.addEllipse(INNER_PATH); + outerPath -= innerPath; + + QPainter painter(this); + painter.setRenderHint(QPainter:: Antialiasing, true); //设置渲染,启动反锯齿 + painter.setPen(Qt::NoPen); + + painter.setBrush(pal.color(QPalette::Base)); + painter.drawPath(cPath); + + painter.fillPath(outerPath, pal.color(QPalette::Text)); + painter.setPen(m_foregroundColor); + QFont font("Noto Sans CJK SC", 11, QFont::Normal, false); + painter.setFont(font); + painter.drawText(TEXT_POS, "i"); +} + +void InfoButton::enterEvent(QEvent *event) +{ + m_foregroundColor = FOREGROUND_COLOR_HOVER; + this->update(); +} + +void InfoButton::leaveEvent(QEvent *event) +{ + m_foregroundColor = FOREGROUND_COLOR_NORMAL; + this->update(); +} + +void InfoButton::mousePressEvent(QMouseEvent *event) +{ + m_foregroundColor = FOREGROUND_COLOR_PRESS; + this->update(); + return QPushButton::mousePressEvent(event); +} + +void InfoButton::mouseReleaseEvent(QMouseEvent *event) +{ + m_foregroundColor = FOREGROUND_COLOR_HOVER; + this->update(); + return QPushButton::mouseReleaseEvent(event); +} diff --git a/src/frontend/tools/infobutton.h b/src/frontend/tools/infobutton.h new file mode 100644 index 00000000..523825ab --- /dev/null +++ b/src/frontend/tools/infobutton.h @@ -0,0 +1,31 @@ +#ifndef INFOBUTTON_H +#define INFOBUTTON_H +#include +#include + +class InfoButton : public QPushButton +{ + Q_OBJECT +public: + explicit InfoButton(QWidget * parent = nullptr); + ~InfoButton() = default; + +protected: + void paintEvent(QPaintEvent *event); + void enterEvent(QEvent *event); + void leaveEvent(QEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + +private: + void initUI(); + +private: + QColor m_backgroundColor; + QColor m_foregroundColor; + +private slots: + void onPaletteChanged(); +}; + +#endif // INFOBUTTON_H diff --git a/src/frontend/tools/kylable.cpp b/src/frontend/tools/kylable.cpp new file mode 100644 index 00000000..0c428a5d --- /dev/null +++ b/src/frontend/tools/kylable.cpp @@ -0,0 +1,97 @@ +#include "kylable.h" +#include +#include +#include + +#define FOREGROUND_COLOR_NORMAL qApp->palette().text().color() + +static inline qreal mixQreal(qreal a, qreal b, qreal bias) +{ + return a + (b - a) * bias; +} + + +QColor mixColor(const QColor &c1, const QColor &c2, qreal bias) +{ + if (bias <= 0.0) { + return c1; + } + if (bias >= 1.0) { + return c2; + } + if (qIsNaN(bias)) { + return c1; + } + + qreal r = mixQreal(c1.redF(), c2.redF(), bias); + qreal g = mixQreal(c1.greenF(), c2.greenF(), bias); + qreal b = mixQreal(c1.blueF(), c2.blueF(), bias); + qreal a = mixQreal(c1.alphaF(), c2.alphaF(), bias); + + return QColor::fromRgbF(r, g, b, a); +} + +KyLable::KyLable(QWidget *parent) : QLabel(parent) +{ + connect(qApp, &QApplication::paletteChanged, this, &KyLable::onPaletteChanged); + onPaletteChanged(); +} + +void KyLable::onPaletteChanged() +{ + m_foregroundColor = FOREGROUND_COLOR_NORMAL; + this->repaint(); +} + +void KyLable::setPressColor() +{ + QColor hightlight = this->palette().color(QPalette::Active,QPalette::Highlight); + QColor mix = this->palette().color(QPalette::Active,QPalette::BrightText); + m_foregroundColor = mixColor(hightlight, mix, 0.05); +} + +void KyLable::setHoverColor() +{ + QColor hightlight = this->palette().color(QPalette::Active,QPalette::Highlight); + QColor mix = this->palette().color(QPalette::Active,QPalette::BrightText); + m_foregroundColor = mixColor(hightlight, mix, 0.2); +} + +void KyLable::setNormalColor() +{ + m_foregroundColor = FOREGROUND_COLOR_NORMAL; +} + +void KyLable::paintEvent(QPaintEvent *event) +{ + QPalette pal = this->palette(); + pal.setColor(QPalette::WindowText, m_foregroundColor); + this->setPalette(pal); + return QLabel::paintEvent(event); +} + +void KyLable::enterEvent(QEvent *event) +{ + setHoverColor(); + this->update(); +} + +void KyLable::leaveEvent(QEvent *event) +{ + setNormalColor(); + this->update(); +} + +void KyLable::mousePressEvent(QMouseEvent *event) +{ + setPressColor(); + this->update(); + return QLabel::mousePressEvent(event); +} + +void KyLable::mouseReleaseEvent(QMouseEvent *event) +{ + setHoverColor(); + this->update(); + return QLabel::mouseReleaseEvent(event); +} diff --git a/src/frontend/tools/kylable.h b/src/frontend/tools/kylable.h new file mode 100644 index 00000000..9b32dfe4 --- /dev/null +++ b/src/frontend/tools/kylable.h @@ -0,0 +1,33 @@ +#ifndef KYLABLE_H +#define KYLABLE_H + +#include +#include + +class KyLable : public QLabel +{ + Q_OBJECT +public: + explicit KyLable(QWidget *parent = nullptr); + ~KyLable() = default; + +protected: + void paintEvent(QPaintEvent *event); + void enterEvent(QEvent *event); + void leaveEvent(QEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + +private: + QColor m_foregroundColor; + + void setPressColor(); + void setHoverColor(); + void setNormalColor(); + +private slots: + void onPaletteChanged(); + +}; + +#endif // KYLABLE_H diff --git a/src/frontend/tools/loadingdiv.cpp b/src/frontend/tools/loadingdiv.cpp new file mode 100644 index 00000000..ddaeef31 --- /dev/null +++ b/src/frontend/tools/loadingdiv.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * 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, 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 + +#define FRAMESPEED 60 //帧与帧之间的间隔时间(ms) +#define ALLTIME 40*1000 //等待动画持续总时间 + +//加载动画控件'loadingGif' +LoadingDiv::LoadingDiv(QWidget *parent) : QWidget(parent) +{ + this->resize(480, 538); + + this->loadingGif = new QLabel(this); + this->loadingGif->resize(96, 96); + this->loadingGif->move(this->width()/2 - 96/2 + 41/2 - 40, this->height()/2 + 20); + this->loadingGif->show(); + + this->switchTimer = new QTimer(this); //QTimer对象,控制等待动画播放 + connect(switchTimer, SIGNAL(timeout()), this, SLOT(switchAnimStep())); + + this->raise(); + this->hide(); +} + +//加载动画控件'loadingGif' +void LoadingDiv::switchAnimStep() +{ + //另外一种加载方法 + QString qpmQss = ":/res/s/conning-b/"; + qpmQss.append(QString::number(this->currentPage)); + qpmQss.append(".png"); + loadingGif->setPixmap(QPixmap(qpmQss)); + loadingGif->setProperty("useIconHighlightEffect", true); + loadingGif->setProperty("iconHighlightEffectMode", true); + + this->currentPage --; + + if (this->currentPage < 1) { + this->currentPage = 12; //循环播放 + } + this->countCurrentTime += FRAMESPEED; + if (this->countCurrentTime >= ALLTIME) { + emit this->toStopLoading(); //发出信号停止主界面和托盘区的等待动画 + } +} + +//开始播放动画 +void LoadingDiv::startLoading() +{ + this->currentPage = 12; + this->countCurrentTime = 0; + this->switchTimer->start(FRAMESPEED); + this->show(); +} + +//结束播放动画 +void LoadingDiv::stopLoading() +{ + this->switchTimer->stop(); + this->hide(); +} diff --git a/src/frontend/tools/loadingdiv.h b/src/frontend/tools/loadingdiv.h new file mode 100644 index 00000000..246e686e --- /dev/null +++ b/src/frontend/tools/loadingdiv.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * 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, 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 +#include +#include +#include +#include +#include + +class LoadingDiv : public QWidget +{ + Q_OBJECT +public: + explicit LoadingDiv(QWidget *parent = nullptr); + +signals: + void toStopLoading(); + +public slots: + void switchAnimStep(); + void startLoading(); + void stopLoading(); + +private: + QLabel *loadingGif = nullptr; + QTimer *switchTimer = nullptr; + + int currentPage; + int countCurrentTime; +}; + +#endif // LOADINGDIV_H diff --git a/src/frontend/tools/radioitembutton.cpp b/src/frontend/tools/radioitembutton.cpp new file mode 100644 index 00000000..0efbf384 --- /dev/null +++ b/src/frontend/tools/radioitembutton.cpp @@ -0,0 +1,246 @@ +#include "radioitembutton.h" +#include +#include +#include +#include +#include +#define FLASH_SPEED 100 +#define TIMEOUT_TIMER 90*1000 +#define BUTTON_SIZE 36,36 +#define ICON_SIZE 16,16 +#define BACKGROUND_COLOR QColor(0,0,0,0) +#define FOREGROUND_COLOR_NORMAL_INACTIVE_LIGHT QColor(230,230,230,255) +#define FOREGROUND_COLOR_NORMAL_INACTIVE_DARK QColor(55,55,55,255) +#define FOREGROUND_COLOR_PRESS_INACTIVE_LIGHT QColor(217,217,217,255) +#define FOREGROUND_COLOR_PRESS_INACTIVE_DARK QColor(70,70,70,255) +#define FOREGROUND_COLOR_NORMAL_ACTIVE QColor(55,144,250,255) +#define FOREGROUND_COLOR_PRESS_ACTIVE QColor(36,109,212,255) + +RadioItemButton::RadioItemButton(QWidget *parent) : QPushButton(parent) +{ + this->setAutoFillBackground(false); + m_iconLabel = new QLabel(this); + + this->setFixedSize(BUTTON_SIZE); + m_iconLabel->setFixedSize(BUTTON_SIZE); + m_iconLabel->setAlignment(Qt::AlignCenter); + + setActive(false); + //JXJ_TODO loading动画 + connect(this, &RadioItemButton::requestStartLoading, this, &RadioItemButton::onLoadingStarted); + connect(this , &RadioItemButton::requestStopLoading, this, &RadioItemButton::onLoadingStopped); + connect(qApp, &QApplication::paletteChanged, this, &RadioItemButton::onPaletteChanged); +} + +RadioItemButton::~RadioItemButton() +{ + +} + +void RadioItemButton::startLoading() +{ + emit this->requestStartLoading(); +} + +void RadioItemButton::stopLoading() +{ + emit this->requestStopLoading(); +} +//设置图标 +void RadioItemButton::setButtonIcon(const QIcon &icon) +{ + if (icon.isNull()) { + return; + } + m_pixmap = icon.pixmap(ICON_SIZE); +// m_iconLabel->setPixmap(m_pixmap); +} +//显示默认图标 +void RadioItemButton::setDefaultPixmap() +{ + m_iconLabel->setPixmap(m_pixmap); +} +//根据连接状态更改图标颜色 +void RadioItemButton::setActive(const bool &isActive) +{ + m_isActivated = isActive; + refreshButtonIcon(); +} +void RadioItemButton::onLoadingStarted() +{ +#define ANIMATION_SPEED 0.5*1000 +#define START_ROTATION 0 +#define END_ROTATION 360 +#define ANIMATION_LOOP -1 //无限旋转 + if (!m_iconLabel) { + qWarning() << "Start loading failed, iconLabel is null pointer!" << Q_FUNC_INFO << __LINE__; + } + if (!m_animation) { + m_animation = new QVariantAnimation(m_iconLabel); + } + m_animation->setDuration(ANIMATION_SPEED); + m_animation->setStartValue(START_ROTATION); + m_animation->setEndValue(END_ROTATION); + m_animation->setLoopCount(ANIMATION_LOOP); + connect(m_animation, &QVariantAnimation::valueChanged, this, &RadioItemButton::onAnimationValueChanged); + m_animation->start(); +} + +void RadioItemButton::onLoadingStopped() +{ + if (!m_animation) { + qWarning() << "Stop loading failed, m_animation is null pointer!" << Q_FUNC_INFO << __LINE__; + return; + } else { + m_iconLabel->setPixmap(m_pixmap); + m_animation->stop(); + emit this->animationStoped(); + } + +} + +void RadioItemButton::onPaletteChanged() +{ + refreshButtonIcon(); +} + +void RadioItemButton::onAnimationValueChanged(const QVariant& value) +{ + if (!m_iconLabel) { + return; + } + QTransform t; + t.rotate(value.toReal()); + m_iconLabel->setPixmap(QIcon(":/res/s/conning-a/1.png").pixmap(ICON_SIZE).transformed(t)); +} + +void RadioItemButton::paintEvent(QPaintEvent *event) +{ + QPalette pal = this->palette(); + pal.setColor(QPalette::Base, BACKGROUND_COLOR); + pal.setColor(QPalette::Text, m_backgroundColor); + + QPainterPath cPath; + cPath.addRect(0, 0, this->width(), this->height()); + cPath.addEllipse(0, 0, this->width(), this->width()); + + QPainterPath innerPath; + innerPath.addEllipse(0, 0, this->width(), this->width()); + + QPainter painter(this); + painter.setRenderHint(QPainter:: Antialiasing, true); //设置渲染,启动反锯齿 + painter.setPen(Qt::NoPen); + + painter.setBrush(pal.color(QPalette::Base)); + painter.drawPath(cPath); + + painter.fillPath(innerPath, pal.color(QPalette::Text)); +} + +void RadioItemButton::mousePressEvent(QMouseEvent *event) +{ + if (m_isActivated) { + m_backgroundColor = qApp->palette().highlight().color(); + } else { + m_backgroundColor = qApp->palette().brightText().color(); + m_backgroundColor.setAlphaF(0.21); + } + this->update(); + return QPushButton::mousePressEvent(event); +} + +void RadioItemButton::mouseReleaseEvent(QMouseEvent *event) +{ + if (m_isActivated) { + m_backgroundColor = qApp->palette().highlight().color(); + } else { + m_backgroundColor = qApp->palette().brightText().color(); + m_backgroundColor.setAlphaF(0.18); + } + this->update(); + return QPushButton::mouseReleaseEvent(event); +} + +void RadioItemButton::enterEvent(QEvent *event) +{ + if (m_isActivated) { + m_backgroundColor = qApp->palette().highlight().color(); + } else { + m_backgroundColor = qApp->palette().brightText().color(); + m_backgroundColor.setAlphaF(0.32); + } + this->update(); + return QPushButton::enterEvent(event); +} + +void RadioItemButton::leaveEvent(QEvent *event) +{ + if (m_isActivated) { + m_backgroundColor = qApp->palette().highlight().color(); + } else { + m_backgroundColor = qApp->palette().brightText().color(); + m_backgroundColor.setAlphaF(0.18); + } + this->update(); + return QPushButton::leaveEvent(event); +} + +void RadioItemButton::refreshButtonIcon() +{ + if (m_isActivated) { + m_backgroundColor = qApp->palette().highlight().color(); + m_iconLabel->setPixmap(loadSvg(m_pixmap, PixmapColor::WHITE)); + } else { + m_backgroundColor = qApp->palette().brightText().color(); + m_backgroundColor.setAlphaF(0.18); + if (qApp->palette().base().color().red() > MIDDLE_COLOR) { + m_iconLabel->setPixmap(m_pixmap); + } else { + m_iconLabel->setPixmap(loadSvg(m_pixmap, PixmapColor::WHITE)); + } + } + + return; +} + +const QPixmap RadioItemButton::loadSvg(const QPixmap &source, const PixmapColor &cgColor) +{ + QImage img = source.toImage(); + for (int x = 0; x < img.width(); x++) { + for (int y = 0; y < img.height(); y++) { + auto color = img.pixelColor(x, y); + if (color.alpha() > 0) { + switch (cgColor) { + case PixmapColor::WHITE: + color.setRed(255); + color.setGreen(255); + color.setBlue(255); + img.setPixelColor(x, y, color); + break; + case PixmapColor::BLACK: + color.setRed(0); + color.setGreen(0); + color.setBlue(0); + img.setPixelColor(x, y, color); + break; + case PixmapColor::GRAY: + color.setRed(152); + color.setGreen(163); + color.setBlue(164); + img.setPixelColor(x, y, color); + break; + case PixmapColor::BLUE: + color.setRed(61); + color.setGreen(107); + color.setBlue(229); + img.setPixelColor(x, y, color); + break; + default: + return source; + break; + } + } + } + } + return QPixmap::fromImage(img); +} diff --git a/src/frontend/tools/radioitembutton.h b/src/frontend/tools/radioitembutton.h new file mode 100644 index 00000000..89ba1a8d --- /dev/null +++ b/src/frontend/tools/radioitembutton.h @@ -0,0 +1,61 @@ +#ifndef NETBUTTON_H +#define NETBUTTON_H +#include +#include +#include +#include +#include + +#define MIDDLE_COLOR 178 + +class RadioItemButton : public QPushButton +{ + Q_OBJECT + +public: + RadioItemButton(QWidget * parent = nullptr); + ~RadioItemButton(); + void startLoading(); + void stopLoading(); + void setButtonIcon(const QIcon &icon); + void setDefaultPixmap(); + void setActive(const bool &isActive); + enum PixmapColor { + WHITE = 0, + BLACK, + GRAY, + BLUE, + }; + const QPixmap loadSvg(const QPixmap &source, const PixmapColor &color); + +signals: + void requestStartLoading(); + void requestStopLoading(); + void animationStoped(); + +protected: + void paintEvent(QPaintEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void enterEvent(QEvent *event); + void leaveEvent(QEvent *event); + +private: + bool m_isActivated = false; + QLabel * m_iconLabel = nullptr; + QColor m_backgroundColor; + QVariantAnimation * m_animation = nullptr; + + QPixmap m_pixmap; + + void refreshButtonIcon(); + +private slots: + void onLoadingStarted(); + void onLoadingStopped(); + void onPaletteChanged(); + void onAnimationValueChanged(const QVariant& value); +}; + +#endif // NETBUTTON_H + diff --git a/src/frontend/tools/switchbutton.cpp b/src/frontend/tools/switchbutton.cpp new file mode 100644 index 00000000..806ca05e --- /dev/null +++ b/src/frontend/tools/switchbutton.cpp @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * 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, 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 setInterval(5); + + if(m_bIsOn == 1) { + m_fCurrentValue = m_fWidth - 16 - 4; + } + else { + m_fCurrentValue = 4; + } + connect(m_cTimer, SIGNAL(timeout()), this, SLOT(startAnimation())); + + +} + +void SwitchButton::setSwitchStatus(bool check) { + if (!m_enabled) + return; + + if(check == true) { + m_bIsOn = 1; + } else { + m_bIsOn = 0; + } + emit this->switchStatusChanged(); + + m_cTimer->start(); //开始播放动画 +} + +bool SwitchButton::getSwitchStatus() +{ + if (m_bIsOn == 1) + return true; + return false; +} + +void SwitchButton::setEnabled(bool enabled) +{ + m_enabled = enabled; + update(); + + return; +} + +bool SwitchButton::getEnabled() +{ + return m_enabled; +} +/* 播放按钮开启关闭动画 */ +void SwitchButton::startAnimation() { //滑动按钮动作播放 + int pos = 4; + int size = m_fWidth - 16; + if(m_bIsOn) { + m_fCurrentValue ++; //往右滑动 + if(m_fCurrentValue >= size - pos) { //到达边界停下来 + m_fCurrentValue = size - pos; + m_cTimer->stop(); + } + } else { + m_fCurrentValue --; + if(m_fCurrentValue <= pos) { //到达最小值,停止继续前进 + m_fCurrentValue = pos; + m_cTimer->stop(); + } + } + update(); +} + +/* 按钮按下处理 */ +void SwitchButton::mousePressEvent(QMouseEvent *event) { + Q_UNUSED(event); + + if (m_enabled) { + m_bIsOn = !m_bIsOn; + } + Q_EMIT clicked(); + return QWidget::mousePressEvent(event); +} + +void SwitchButton::enterEvent(QEvent *event) +{ + if (m_enabled && m_bIsOn) { + m_colorActive = COLOR_ACTIVE_HOVER; + } else if (m_enabled && !m_bIsOn) { + m_colorInactive = COLOR_INACTIVE_HOVER; + } + + this->update(); + + return QWidget::enterEvent(event); +} + +void SwitchButton::leaveEvent(QEvent *event) +{ + if (m_enabled && m_bIsOn) { + m_colorActive = COLOR_ACTIVE; + } else if (m_enabled && !m_bIsOn) { + m_colorInactive = COLOR_INACTIVE; + } + + this->update(); + + return QWidget::leaveEvent(event); +} + +/* 绘制滑动按钮主体 */ +void SwitchButton::paintEvent(QPaintEvent *event) { + Q_UNUSED(event); + QPainter painter(this); + painter.setRenderHint(QPainter::SmoothPixmapTransform); + painter.setRenderHint(QPainter::Antialiasing); //抗锯齿效果 + painter.setPen(Qt::NoPen); + if(m_bIsOn && m_enabled) { + painter.save(); + painter.setBrush(m_colorActive); + QRectF active_rect = QRectF(0,0,m_fWidth,m_fHeight); + painter.drawRoundedRect(active_rect, 0.5 * m_fHeight, 0.5 * m_fHeight); //画开启状态 + } else { + painter.save(); + painter.setBrush(m_colorInactive); + QRectF inactive_rect = QRectF(0 ,0,m_fWidth,m_fHeight); + painter.drawRoundedRect(inactive_rect, 0.5 * m_fHeight, 0.5 * m_fHeight); //画关闭状态 + } + painter.restore(); + painter.save(); + if (!m_enabled) { + painter.setBrush(COLOR_UNABLE); +// QRectF enableRect = QRectF(30, 10, 8, 4); +// painter.drawRoundedRect(enableRect, 2, 2); + } else { + painter.setBrush(Qt::white); + } + painter.drawEllipse(m_fCurrentValue,4, 16, 16); + + painter.restore(); +} + diff --git a/src/frontend/tools/switchbutton.h b/src/frontend/tools/switchbutton.h new file mode 100644 index 00000000..fea1e480 --- /dev/null +++ b/src/frontend/tools/switchbutton.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * 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, 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 +#include +#include +#include + +class SwitchButton : public QWidget +{ + Q_OBJECT +public: + explicit SwitchButton(QWidget *parent = nullptr); + void setSwitchStatus(bool check); + bool getSwitchStatus(); + void setEnabled(bool enabled); + bool getEnabled(); + +private: + QColor m_colorActive; + QColor m_colorInactive; + int m_bIsOn = 1; + QTimer *m_cTimer; + float m_fWidth; + float m_fHeight; + float m_fCurrentValue; + void paintEvent(QPaintEvent *event); + void mousePressEvent(QMouseEvent *event); + void enterEvent(QEvent *event); + void leaveEvent(QEvent *event); + bool m_enabled = true; + +Q_SIGNALS: + void clicked(); + void switchStatusChanged(); + +private Q_SLOTS: + void startAnimation(); + +}; + +#endif // SWITCHBUTTON_H diff --git a/src/frontend/tools/tools.pri b/src/frontend/tools/tools.pri new file mode 100644 index 00000000..7863428b --- /dev/null +++ b/src/frontend/tools/tools.pri @@ -0,0 +1,18 @@ +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/divider.h \ + $$PWD/infobutton.h \ + $$PWD/loadingdiv.h \ + $$PWD/radioitembutton.h \ + $$PWD/switchbutton.h \ + $$PWD/kylable.h + + +SOURCES += \ + $$PWD/divider.cpp \ + $$PWD/infobutton.cpp \ + $$PWD/loadingdiv.cpp \ + $$PWD/radioitembutton.cpp \ + $$PWD/switchbutton.cpp \ + $$PWD/kylable.cpp diff --git a/src/frontend/wificonfigdialog.cpp b/src/frontend/wificonfigdialog.cpp new file mode 100644 index 00000000..23d2d24e --- /dev/null +++ b/src/frontend/wificonfigdialog.cpp @@ -0,0 +1,199 @@ +#include "wificonfigdialog.h" +#include "ui_wificonfigdialog.h" +#include "utils.h" + +#include +#include +#include +#include + +#include + +WiFiConfigDialog::WiFiConfigDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::WiFiConfigDialog) +{ + ui->setupUi(this); + + initTransparentState(); //初始化窗口透明度的GSetting方法 + + this->setWindowFlags(Qt::FramelessWindowHint); //Qt::WindowStaysOnTopHint + this->setWindowTitle(tr("WLAN Authentication"));//"Wifi 认证" + this->setAttribute(Qt::WA_TranslucentBackground); + this->setWindowIcon(QIcon::fromTheme("kylin-network", QIcon(":/res/x/setup.png")) ); + + QPainterPath path; + auto rect = this->rect(); + rect.adjust(1, 1, -1, -1); + path.addRoundedRect(rect, 6, 6); + setProperty("blurRegion", QRegion(path.toFillPolygon().toPolygon())); + KWindowEffects::enableBlurBehind(this->winId(), true, QRegion(path.toFillPolygon().toPolygon())); + + ui->lbTitle->setText(tr("Input WLAN Information Please")); //输入Wi-Fi名称和密码后点击确定 + ui->lbWifiId->setText(tr("WLAN ID:")); //Wi-Fi连接名称: + ui->lbWifiName->setText(tr("WLAN Name:")); //Wi-Fi名称: + ui->lbWifiPassord->setText(tr("Password:")); //Wi-Fi密码: + ui->btnCancel->setText(tr("Cancl")); + ui->btnOk->setText(tr("Ok")); + ui->leWifiId->setContextMenuPolicy(Qt::NoContextMenu); + ui->leWiFiName->setContextMenuPolicy(Qt::NoContextMenu); + + ui->leWifiPassword->setContextMenuPolicy(Qt::NoContextMenu); + ui->leWifiPassword ->setEchoMode(QLineEdit::Password); + + ui->checkBoxPwd->setStyleSheet(checkBoxQss); + ui->checkBoxPwd->setFocusPolicy(Qt::NoFocus); + + ui->leWifiId->setContextMenuPolicy(Qt::NoContextMenu); //禁止LineEdit的右键菜单 + ui->leWiFiName->setContextMenuPolicy(Qt::NoContextMenu); + ui->leWifiPassword->setContextMenuPolicy(Qt::NoContextMenu); + + this->setEnableOfBtn(); + this->setFixedSize(474, 320); +} + +WiFiConfigDialog::~WiFiConfigDialog() +{ + delete ui; +} + +void WiFiConfigDialog::paintEvent(QPaintEvent *event) +{ + double trans = this->getTransparentData(); + + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); + + QRect rect = this->rect(); + p.setRenderHint(QPainter::Antialiasing); // 反锯齿; + p.setBrush(opt.palette.color(QPalette::Base)); + p.setOpacity(trans); + p.setPen(Qt::NoPen); + p.drawRoundedRect(rect, 6, 6); + QWidget::paintEvent(event); +} + +//创建获取窗口透明度信息的GSetting的对象 +void WiFiConfigDialog::initTransparentState() +{ + if (QGSettings::isSchemaInstalled("org.ukui.control-center.personalise")) { + m_transparency_gsettings = new QGSettings("org.ukui.control-center.personalise"); + } +} + +//使用GSetting获取当前窗口应该使用的透明度 +double WiFiConfigDialog::getTransparentData() +{ + if (!m_transparency_gsettings) { + return 0.7; + } + + QStringList keys = m_transparency_gsettings->keys(); + if (keys.contains("transparency")) { + double tp = m_transparency_gsettings->get("transparency").toDouble(); + return tp; + } else { + return 0.7; + } +} + +void WiFiConfigDialog::on_btnCancel_clicked() +{ + ui->leWiFiName->setText(""); + ui->leWifiPassword->setText(""); + hide(); +} + +void WiFiConfigDialog::on_btnOk_clicked() +{ + QFuture < void > future1 = QtConcurrent::run([=](){ + this->toConfigWifi(); + }); + hide(); +} + +void WiFiConfigDialog::toConfigWifi() +{ + QString connName = ui->leWiFiName->text(); + QString password = ui->leWifiPassword->text(); + + QString strConntype = "nmcli connection modify '" + connName + "' wifi-sec.psk-flags 0"; + Utils::m_system(strConntype.toUtf8().data()); + + QString tmpPath = "/tmp/kylin-nm-btoutput-" + QDir::home().dirName(); + QString cmdStr = "export LANG='en_US.UTF-8';export LANGUAGE='en_US';nmcli device wifi connect '" + connName + "' password '" + password + "' > " + tmpPath; + Utils::m_system(cmdStr.toUtf8().data()); + + QFile file(tmpPath); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + qDebug()<<"Can't open the file /tmp/kylin-nm-btoutput in function toConfigWifi !"; + } + QString line = file.readLine(); + file.close(); + qDebug()<<"connect_wifi_result: "<< line; + + if (line.indexOf("successfully") != -1) { + QString strConntype = "nmcli connection modify '" + connName + "' wifi-sec.psk-flags 2"; + system(strConntype.toUtf8().data()); + } else { + QString cmd = "export LANG='en_US.UTF-8';export LANGUAGE='en_US';nmcli connection delete '" + ui->leWifiId->text() + "'"; + int status = system(cmd.toUtf8().data()); + qDebug()<<"executed cmd="< + + WiFiConfigDialog + + + + 0 + 0 + 474 + 320 + + + + Dialog + + + + + 60 + 30 + 290 + 30 + + + + + + + + + + 60 + 140 + 90 + 30 + + + + + + + + + + 60 + 200 + 90 + 30 + + + + + + + + + + 190 + 140 + 240 + 30 + + + + + + + 190 + 200 + 241 + 30 + + + + + + + 220 + 260 + 96 + 36 + + + + + + + + + + 330 + 260 + 96 + 36 + + + + + + + + + + 60 + 80 + 121 + 30 + + + + + + + + + + 190 + 80 + 240 + 30 + + + + + + + 400 + 211 + 18 + 9 + + + + + + + + + + diff --git a/src/frontend/xatom/xatom-helper.cpp b/src/frontend/xatom/xatom-helper.cpp new file mode 100644 index 00000000..cf7b2936 --- /dev/null +++ b/src/frontend/xatom/xatom-helper.cpp @@ -0,0 +1,210 @@ +/* + * KWin Style UKUI + * + * Copyright (C) 2020, KylinSoft Co., Ltd. + * + * 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 . + * + * Authors: Yue Lan + * + */ + +#include "xatom-helper.h" +#include +#include +#include +#include + +static XAtomHelper *global_instance = nullptr; + +XAtomHelper *XAtomHelper::getInstance() +{ + if(!global_instance) + global_instance = new XAtomHelper; + return global_instance; +} + +bool XAtomHelper::isFrameLessWindow(int winId) +{ + auto hints = getInstance()->getWindowMotifHint(winId); + if(hints.flags == MWM_HINTS_DECORATIONS && hints.functions == 1) { + return true; + } + return false; +} + +bool XAtomHelper::isWindowDecorateBorderOnly(int winId) +{ + return isWindowMotifHintDecorateBorderOnly(getInstance()->getWindowMotifHint(winId)); +} + +bool XAtomHelper::isWindowMotifHintDecorateBorderOnly(const MotifWmHints &hint) { + bool isDeco = false; + if(hint.flags & MWM_HINTS_DECORATIONS && hint.flags != MWM_HINTS_DECORATIONS) { + if(hint.decorations == MWM_DECOR_BORDER) + isDeco = true; + } + return isDeco; +} + +bool XAtomHelper::isUKUICsdSupported() +{ + // fixme: + return false; +} + +bool XAtomHelper::isUKUIDecorationWindow(int winId) +{ + if(m_ukuiDecorationAtion == None) + return false; + + Atom type; + int format; + ulong nitems; + ulong bytes_after; + uchar *data; + + bool isUKUIDecoration = false; + + XGetWindowProperty(QX11Info::display(), winId, m_ukuiDecorationAtion, + 0, LONG_MAX, false, + m_ukuiDecorationAtion, &type, + &format, &nitems, + &bytes_after, &data); + + if(type == m_ukuiDecorationAtion) { + if(nitems == 1) { + isUKUIDecoration = data[0]; + } + } + + return isUKUIDecoration; +} + +UnityCorners XAtomHelper::getWindowBorderRadius(int winId) +{ + UnityCorners corners; + + Atom type; + int format; + ulong nitems; + ulong bytes_after; + uchar *data; + + if(m_unityBorderRadiusAtom != None) { + XGetWindowProperty(QX11Info::display(), winId, m_unityBorderRadiusAtom, + 0, LONG_MAX, false, + XA_CARDINAL, &type, + &format, &nitems, + &bytes_after, &data); + + if(type == XA_CARDINAL) { + if(nitems == 4) { + corners.topLeft = static_cast(data[0]); + corners.topRight = static_cast(data[1 * sizeof(ulong)]); + corners.bottomLeft = static_cast(data[2 * sizeof(ulong)]); + corners.bottomRight = static_cast(data[3 * sizeof(ulong)]); + } + XFree(data); + } + } + + return corners; +} + +void XAtomHelper::setWindowBorderRadius(int winId, const UnityCorners &data) +{ + if(m_unityBorderRadiusAtom == None) + return; + + ulong corners[4] = {data.topLeft, data.topRight, data.bottomLeft, data.bottomRight}; + + XChangeProperty(QX11Info::display(), winId, m_unityBorderRadiusAtom, XA_CARDINAL, + 32, XCB_PROP_MODE_REPLACE, (const unsigned char *) &corners, sizeof(corners) / sizeof(corners[0])); +} + +void XAtomHelper::setWindowBorderRadius(int winId, int topLeft, int topRight, int bottomLeft, int bottomRight) +{ + if(m_unityBorderRadiusAtom == None) + return; + + ulong corners[4] = {(ulong)topLeft, (ulong)topRight, (ulong)bottomLeft, (ulong)bottomRight}; + + XChangeProperty(QX11Info::display(), winId, m_unityBorderRadiusAtom, XA_CARDINAL, + 32, XCB_PROP_MODE_REPLACE, (const unsigned char *) &corners, sizeof(corners) / sizeof(corners[0])); +} + +void XAtomHelper::setUKUIDecoraiontHint(int winId, bool set) +{ + if(m_ukuiDecorationAtion == None) + return; + + XChangeProperty(QX11Info::display(), winId, m_ukuiDecorationAtion, m_ukuiDecorationAtion, 32, XCB_PROP_MODE_REPLACE, (const unsigned char *) &set, 1); +} + +void XAtomHelper::setWindowMotifHint(int winId, const MotifWmHints &hints) +{ + if(m_unityBorderRadiusAtom == None) + return; + + XChangeProperty(QX11Info::display(), winId, m_motifWMHintsAtom, m_motifWMHintsAtom, + 32, XCB_PROP_MODE_REPLACE, (const unsigned char *)&hints, sizeof(MotifWmHints) / sizeof(ulong)); +} + +MotifWmHints XAtomHelper::getWindowMotifHint(int winId) +{ + MotifWmHints hints; + + if(m_unityBorderRadiusAtom == None) + return hints; + + uchar *data; + Atom type; + int format; + ulong nitems; + ulong bytes_after; + + XGetWindowProperty(QX11Info::display(), winId, m_motifWMHintsAtom, + 0, sizeof(MotifWmHints) / sizeof(long), false, AnyPropertyType, &type, + &format, &nitems, &bytes_after, &data); + + if(type == None) { + return hints; + } else { + hints = *(MotifWmHints *)data; + XFree(data); + } + return hints; +} + +XAtomHelper::XAtomHelper(QObject *parent) : QObject(parent) +{ + if(!QX11Info::isPlatformX11()) + return; + + m_motifWMHintsAtom = XInternAtom(QX11Info::display(), "_MOTIF_WM_HINTS", true); + m_unityBorderRadiusAtom = XInternAtom(QX11Info::display(), "_UNITY_GTK_BORDER_RADIUS", false); + m_ukuiDecorationAtion = XInternAtom(QX11Info::display(), "_KWIN_UKUI_DECORAION", false); +} + +Atom XAtomHelper::registerUKUICsdNetWmSupportAtom() +{ + // fixme: + return None; +} + +void XAtomHelper::unregisterUKUICsdNetWmSupportAtom() +{ + // fixme: +} diff --git a/src/frontend/xatom/xatom-helper.h b/src/frontend/xatom/xatom-helper.h new file mode 100644 index 00000000..87272454 --- /dev/null +++ b/src/frontend/xatom/xatom-helper.h @@ -0,0 +1,110 @@ +/* + * KWin Style UKUI + * + * Copyright (C) 2020, KylinSoft Co., Ltd. + * + * 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 . + * + * Authors: Yue Lan + * + */ + +#ifndef XATOMHELPER_H +#define XATOMHELPER_H + +#include +#include +#include + +struct UnityCorners { + ulong topLeft = 0; + ulong topRight = 0; + ulong bottomLeft = 0; + ulong bottomRight = 0; +}; + +typedef struct { + ulong flags = 0; + ulong functions = 0; + ulong decorations = 0; + long input_mode = 0; + ulong status = 0; +} MotifWmHints, MwmHints; + +#define MWM_HINTS_FUNCTIONS (1L << 0) +#define MWM_HINTS_DECORATIONS (1L << 1) +#define MWM_HINTS_INPUT_MODE (1L << 2) +#define MWM_HINTS_STATUS (1L << 3) + +#define MWM_FUNC_ALL (1L << 0) +#define MWM_FUNC_RESIZE (1L << 1) +#define MWM_FUNC_MOVE (1L << 2) +#define MWM_FUNC_MINIMIZE (1L << 3) +#define MWM_FUNC_MAXIMIZE (1L << 4) +#define MWM_FUNC_CLOSE (1L << 5) + +#define MWM_DECOR_ALL (1L << 0) +#define MWM_DECOR_BORDER (1L << 1) +#define MWM_DECOR_RESIZEH (1L << 2) +#define MWM_DECOR_TITLE (1L << 3) +#define MWM_DECOR_MENU (1L << 4) +#define MWM_DECOR_MINIMIZE (1L << 5) +#define MWM_DECOR_MAXIMIZE (1L << 6) + +#define MWM_INPUT_MODELESS 0 +#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1 +#define MWM_INPUT_SYSTEM_MODAL 2 +#define MWM_INPUT_FULL_APPLICATION_MODAL 3 +#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL + +#define MWM_TEAROFF_WINDOW (1L<<0) + +namespace UKUI { +class Decoration; +} + +class XAtomHelper : public QObject +{ + // friend class UKUI::Decoration; + Q_OBJECT +public: + static XAtomHelper *getInstance(); + + static bool isFrameLessWindow(int winId); + + static bool isWindowDecorateBorderOnly(int winId); + static bool isWindowMotifHintDecorateBorderOnly(const MotifWmHints &hint); + bool isUKUICsdSupported(); + bool isUKUIDecorationWindow(int winId); + + UnityCorners getWindowBorderRadius(int winId); + void setWindowBorderRadius(int winId, const UnityCorners &data); + void setWindowBorderRadius(int winId, int topLeft, int topRight, int bottomLeft, int bottomRight); + void setUKUIDecoraiontHint(int winId, bool set = true); + + void setWindowMotifHint(int winId, const MotifWmHints &hints); + MotifWmHints getWindowMotifHint(int winId); + +private: + explicit XAtomHelper(QObject *parent = nullptr); + + Atom registerUKUICsdNetWmSupportAtom(); + void unregisterUKUICsdNetWmSupportAtom(); + + Atom m_motifWMHintsAtom = None; + Atom m_unityBorderRadiusAtom = None; + Atom m_ukuiDecorationAtion = None; +}; + +#endif // XATOMHELPER_H diff --git a/src/frontend/xatom/xatom.pri b/src/frontend/xatom/xatom.pri new file mode 100644 index 00000000..2d5b1409 --- /dev/null +++ b/src/frontend/xatom/xatom.pri @@ -0,0 +1,7 @@ +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/xatom-helper.h \ + +SOURCES += \ + $$PWD/xatom-helper.cpp \ diff --git a/src/kylin-nm.desktop b/src/kylin-nm.desktop new file mode 100644 index 00000000..849c402e --- /dev/null +++ b/src/kylin-nm.desktop @@ -0,0 +1,18 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Kylin NM +Name[zh_CN]=麒麟网络设置工具 +Name[zh_HK]=麒麟網路設置工具 +Name[zh_TW]=麒麟網路設置工具 +Icon=gnome-dev-ethernet +Comment=Beautiful Network Config Applet +Comment[zh_CN]=麒麟网络设置工具,提供查看和简单设置功能,拥有美观的界面和舒适的操作. +Keywords=applet;nm;network;network-manager; +Exec=/usr/bin/kylin-nm +StartupNotify=false +Terminal=false +Type=Application +OnlyShowIn=UKUI +X-UKUI-AutoRestart=true +NoDisplay=true +X-UKUI-Autostart-Phase=Application diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 00000000..836471f7 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. + * + * 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, 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 +#include +#include "qt-single-application.h" +#include +#include +#include +#include +#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) +#include "xatom-helper.h" +#endif + +#define LOG_IDENT "ukui_kylin_nm" + +const QString QT_TRANSLATE_FILE = "/usr/share/qt5/translations/qt_zh_CN.qm"; + +void messageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) +{ + QByteArray localMsg = msg.toLocal8Bit(); + QByteArray currentDateTime = QDateTime::currentDateTime().toString().toLocal8Bit(); + + bool showDebug = true; + QString logFilePath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/.config/ukui/kylin-nm.log"; + //若不需要自动创建日志文件,请放开此注释 +// if (!QFile::exists(logFilePath)) { +// showDebug = false; +// } + FILE *log_file = nullptr; + + if (showDebug) { + log_file = fopen(logFilePath.toLocal8Bit().constData(), "a+"); + } + + const char *file = context.file ? context.file : ""; + const char *function = context.function ? context.function : ""; + switch (type) { + case QtDebugMsg: + if (!log_file) { + break; + } + fprintf(log_file, "Debug: %s: %s (%s:%u, %s)\n", currentDateTime.constData(), localMsg.constData(), file, context.line, function); + break; + case QtInfoMsg: + fprintf(log_file? log_file: stdout, "Info: %s: %s (%s:%u, %s)\n", currentDateTime.constData(), localMsg.constData(), file, context.line, function); + break; + case QtWarningMsg: + fprintf(log_file? log_file: stderr, "Warning: %s: %s (%s:%u, %s)\n", currentDateTime.constData(), localMsg.constData(), file, context.line, function); + break; + case QtCriticalMsg: + fprintf(log_file? log_file: stderr, "Critical: %s: %s (%s:%u, %s)\n", currentDateTime.constData(), localMsg.constData(), file, context.line, function); + break; + case QtFatalMsg: + fprintf(log_file? log_file: stderr, "Fatal: %s: %s (%s:%u, %s)\n", currentDateTime.constData(), localMsg.constData(), file, context.line, function); + break; + } + + if (log_file) + fclose(log_file); +} + +int main(int argc, char *argv[]) +{ + initUkuiLog4qt("kylin-nm"); + + QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); + +// QApplication a(argc, argv); + QString id = QString("kylin-nm"+ QLatin1String(getenv("DISPLAY"))); + QtSingleApplication a(id, argc, argv); + + QApplication::setQuitOnLastWindowClosed(false); + + + QCommandLineParser parser; + parser.setApplicationDescription(QCoreApplication::translate("main", "kylinnm")); + parser.addHelpOption(); + parser.addVersionOption(); + + QCommandLineOption swOption(QStringLiteral("sw"),QCoreApplication::translate("main", "show kylin-nm wifi page")); + QCommandLineOption snOption(QStringLiteral("sn"),QCoreApplication::translate("main", "show kylin-nm lan page")); + + parser.addOptions({swOption,snOption}); + parser.process(a); + + QDBusInterface interface("com.kylin.network", + "/com/kylin/network", + "com.kylin.network", + QDBusConnection::sessionBus()); + if(interface.isValid()) { + if (parser.isSet(swOption)) + { + interface.call(QStringLiteral("showKylinNM"),1); + } else { + interface.call(QStringLiteral("showKylinNM"),0); + } + return 0; + } + + QThread thread; + KyNetworkResourceManager *p_networkResource = KyNetworkResourceManager::getInstance(); + p_networkResource->moveToThread(&thread); + QObject::connect(&thread, SIGNAL(started()), p_networkResource, SLOT(onInitNetwork())); + thread.start(); + + // Internationalization + QString locale = QLocale::system().name(); + QTranslator trans_global; + qDebug() << "QLocale " << QLocale(); + if (trans_global.load(QLocale(), "kylin-nm", "_", ":/translations/")) + { + a.installTranslator(&trans_global); + qDebug()<<"Translations load success"; + } else { + qWarning() << "Translations load fail"; + } + + QTranslator qtBaseTranslator; + if (qtBaseTranslator.load(QLocale(), "qt", "_", "/usr/share/qt5/translations/")) + { + a.installTranslator(&qtBaseTranslator); + qDebug()<<"QtBase Translations load success"; + } else { + qWarning() << "QtBase Translations load fail"; + } + + while (!p_networkResource->NetworkManagerIsInited()) { + ::usleep(1000); + } + + MainWindow w; + a.setActivationWindow(&w); + w.setProperty("useStyleWindowManager", false); //禁用拖动 + //设置窗口无边框,阴影 + + MotifWmHints window_hints; + window_hints.flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS; + window_hints.functions = MWM_FUNC_ALL; + window_hints.decorations = MWM_DECOR_BORDER; + XAtomHelper::getInstance()->setWindowMotifHint(w.winId(), window_hints); + +// w.setWindowFlags(Qt::CustomizeWindowHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint); + + + DbusAdaptor adaptor(&w); + Q_UNUSED(adaptor); + + auto connection = QDBusConnection::sessionBus(); + if (!connection.registerService("com.kylin.network") || !connection.registerObject("/com/kylin/network", &w)) { + qCritical() << "QDbus register service failed reason:" << connection.lastError(); + } + + return a.exec(); +} diff --git a/src/org.ukui.kylin-nm.switch.gschema.xml b/src/org.ukui.kylin-nm.switch.gschema.xml new file mode 100644 index 00000000..544f2cd0 --- /dev/null +++ b/src/org.ukui.kylin-nm.switch.gschema.xml @@ -0,0 +1,14 @@ + + + + true + wireless switch + Wireless switch.true is open,false is close. + + + true + wired switch + Wired switch.true is open,false is close. + + + diff --git a/src/singleapplication/qt-local-peer.cpp b/src/singleapplication/qt-local-peer.cpp new file mode 100644 index 00000000..4a62537c --- /dev/null +++ b/src/singleapplication/qt-local-peer.cpp @@ -0,0 +1,205 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies) +** 2020 KylinSoft Co., Ltd. +** Contact: http://www.qt-project.org/legal +** +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +** +****************************************************************************/ + + +#include "qt-local-peer.h" +#include +#include +#include + +#if defined(Q_OS_UNIX) +#include +#include +#include +#endif + +namespace QtLP_Private { +#include "qt-locked-file.cpp" +#include "qt-locked-file-unix.cpp" +} + +const char* QtLocalPeer::ack = "ack"; + +QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId) + : QObject(parent), id(appId) { + QString prefix = id; + if(id.isEmpty()) { + id = QCoreApplication::applicationFilePath(); +#if defined(Q_OS_WIN) + id = id.toLower(); +#endif + prefix = id.section(QLatin1Char('/'), -1); //完整路径按‘/’分隔后取最后一个字段 + } + prefix.remove(QRegExp("[^a-zA-Z]")); //去掉名称中的非字母 + prefix.truncate(6); //取前六位 + + QByteArray idc = id.toUtf8(); + quint16 idNum = qChecksum(idc.constData(), idc.size()); + socketName = QLatin1String("qtsingleapp-") + prefix + + QLatin1Char('-') + QString::number(idNum, 16); + +#if defined(Q_OS_WIN) + if(!pProcessIdToSessionId) { + QLibrary lib("kernel32"); + pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId"); + } + if(pProcessIdToSessionId) { + DWORD sessionId = 0; + pProcessIdToSessionId(GetCurrentProcessId(), &sessionId); + socketName += QLatin1Char('-') + QString::number(sessionId, 16); + } +#else + socketName += QLatin1Char('-') + QString::number(::getuid(), 16); +#endif + + server = new QLocalServer(this); + QString lockName = QDir(QDir::tempPath()).absolutePath() + + QLatin1Char('/') + socketName + + QLatin1String("-lockfile"); //tmp目录下的锁文件 + lockFile.setFileName(lockName); + lockFile.open(QIODevice::ReadWrite); +} + + + +bool QtLocalPeer::isClient() { + if(lockFile.isLocked()) + return false; + + if(!lockFile.lock(QtLP_Private::QtLockedFile::WriteLock, false)) + return true; + + //由于文件锁的存在,仅当本进程第一次启动时能执行到此并使server进行监听和关联槽函数 + bool res = server->listen(socketName); +#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(4,5,0)) + // ### Workaround + if(!res && server->serverError() == QAbstractSocket::AddressInUseError) { + QFile::remove(QDir::cleanPath(QDir::tempPath()) + QLatin1Char('/') + socketName); + res = server->listen(socketName); + } +#endif + if(!res) + qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString())); + QObject::connect(server, &QLocalServer::newConnection, this, &QtLocalPeer::receiveConnection); + return false; +} + + +bool QtLocalPeer::sendMessage(const QString &message, int timeout) { + if(!isClient()) + return false; + + QLocalSocket socket; + bool connOk = false; + for(int i = 0; i < 2; i++) { + // Try twice, in case the other instance is just starting up + socket.connectToServer(socketName); + connOk = socket.waitForConnected(timeout / 2); + if(connOk || i) + break; + int ms = 250; +#if defined(Q_OS_WIN) + Sleep(DWORD(ms)); +#else + struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 }; + nanosleep(&ts, NULL); +#endif + } + if(!connOk) + return false; + + QByteArray uMsg(message.toUtf8()); + QDataStream ds(&socket); + ds.writeBytes(uMsg.constData(), uMsg.size()); + bool res = socket.waitForBytesWritten(timeout); + if(res) { + res &= socket.waitForReadyRead(timeout); // wait for ack + if(res) + res &= (socket.read(qstrlen(ack)) == ack); + } + return res; +} + +/** + * @brief QtLocalPeer::receiveConnection 当新进程启动时,会尝试连接此进程server,server接收到newConnection信号并触发此槽函数 + */ +void QtLocalPeer::receiveConnection() { + QLocalSocket* socket = server->nextPendingConnection(); //获取新进程的socket + if(!socket) + return; + + while(true) { + if(socket->state() == QLocalSocket::UnconnectedState) { + qWarning("QtLocalPeer: Peer disconnected"); + delete socket; + return; + } + if(socket->bytesAvailable() >= qint64(sizeof(quint32))) + break; + socket->waitForReadyRead(); + } + + QDataStream ds(socket); + QByteArray uMsg; + quint32 remaining; + ds >> remaining; + uMsg.resize(remaining); + int got = 0; + char* uMsgBuf = uMsg.data(); + do { + got = ds.readRawData(uMsgBuf, remaining); + remaining -= got; + uMsgBuf += got; + } while(remaining && got >= 0 && socket->waitForReadyRead(2000)); + if(got < 0) { + qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData()); + delete socket; + return; + } + QString message(QString::fromUtf8(uMsg)); + socket->write(ack, qstrlen(ack)); + socket->waitForBytesWritten(1000); + socket->waitForDisconnected(1000); // make sure client reads ack + delete socket; + Q_EMIT messageReceived(message); //获取新进程的启动信息并作为信号发送给前端 +} diff --git a/src/singleapplication/qt-local-peer.h b/src/singleapplication/qt-local-peer.h new file mode 100644 index 00000000..883aec2a --- /dev/null +++ b/src/singleapplication/qt-local-peer.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies) +** 2020 KylinSoft Co., Ltd. +** Contact: http://www.qt-project.org/legal +** +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +** +****************************************************************************/ + +#ifndef QTLOCALPEER_H +#define QTLOCALPEER_H + +#include +#include +#include + +#include "qt-locked-file.h" + +class QtLocalPeer : public QObject { + Q_OBJECT + +public: + QtLocalPeer(QObject *parent = 0, const QString &appId = QString()); + bool isClient(); + bool sendMessage(const QString &message, int timeout); + QString applicationId() const { + return id; + } + +Q_SIGNALS: + void messageReceived(const QString &message); + +protected Q_SLOTS: + void receiveConnection(); + +protected: + QString id; + QString socketName; + QLocalServer* server; + QtLP_Private::QtLockedFile lockFile; + +private: + static const char* ack; +}; + +#endif // QTLOCALPEER_H diff --git a/src/singleapplication/qt-locked-file-unix.cpp b/src/singleapplication/qt-locked-file-unix.cpp new file mode 100644 index 00000000..51472520 --- /dev/null +++ b/src/singleapplication/qt-locked-file-unix.cpp @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies) +** 2020 KylinSoft Co., Ltd. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include + +#include "qt-locked-file.h" + +bool QtLockedFile::lock(LockMode mode, bool block) { + if(!isOpen()) { + qWarning("QtLockedFile::lock(): file is not opened"); + return false; + } + + if(mode == NoLock) + return unlock(); + + if(mode == m_lock_mode) + return true; + + if(m_lock_mode != NoLock) + unlock(); + + struct flock fl; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK; + int cmd = block ? F_SETLKW : F_SETLK; + int ret = fcntl(handle(), cmd, &fl); + + if(ret == -1) { + if(errno != EINTR && errno != EAGAIN) + qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); + return false; + } + + + m_lock_mode = mode; + return true; +} + + +bool QtLockedFile::unlock() { + if(!isOpen()) { + qWarning("QtLockedFile::unlock(): file is not opened"); + return false; + } + + if(!isLocked()) + return true; + + struct flock fl; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + fl.l_type = F_UNLCK; + int ret = fcntl(handle(), F_SETLKW, &fl); + + if(ret == -1) { + qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); + return false; + } + + m_lock_mode = NoLock; + return true; +} + +QtLockedFile::~QtLockedFile() { + if(isOpen()) + unlock(); +} + diff --git a/src/singleapplication/qt-locked-file.cpp b/src/singleapplication/qt-locked-file.cpp new file mode 100644 index 00000000..707b4cfa --- /dev/null +++ b/src/singleapplication/qt-locked-file.cpp @@ -0,0 +1,189 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies) +** 2020 KylinSoft Co., Ltd. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qt-locked-file.h" + +/*! + \class QtLockedFile + + \brief The QtLockedFile class extends QFile with advisory locking + functions. + + A file may be locked in read or write mode. Multiple instances of + \e QtLockedFile, created in multiple processes running on the same + machine, may have a file locked in read mode. Exactly one instance + may have it locked in write mode. A read and a write lock cannot + exist simultaneously on the same file. + + The file locks are advisory. This means that nothing prevents + another process from manipulating a locked file using QFile or + file system functions offered by the OS. Serialization is only + guaranteed if all processes that access the file use + QLockedFile. Also, while holding a lock on a file, a process + must not open the same file again (through any API), or locks + can be unexpectedly lost. + + The lock provided by an instance of \e QtLockedFile is released + whenever the program terminates. This is true even when the + program crashes and no destructors are called. +*/ + +/*! \enum QtLockedFile::LockMode + + This enum describes the available lock modes. + + \value ReadLock A read lock. + \value WriteLock A write lock. + \value NoLock Neither a read lock nor a write lock. +*/ + +/*! + Constructs an unlocked \e QtLockedFile object. This constructor + behaves in the same way as \e QFile::QFile(). + + \sa QFile::QFile() +*/ +QtLockedFile::QtLockedFile() + : QFile() { +#ifdef Q_OS_WIN + wmutex = 0; + rmutex = 0; +#endif + m_lock_mode = NoLock; +} + +/*! + Constructs an unlocked QtLockedFile object with file \a name. This + constructor behaves in the same way as \e QFile::QFile(const + QString&). + + \sa QFile::QFile() +*/ +QtLockedFile::QtLockedFile(const QString &name) + : QFile(name) { +#ifdef Q_OS_WIN + wmutex = 0; + rmutex = 0; +#endif + m_lock_mode = NoLock; +} + +/*! + Opens the file in OpenMode \a mode. + + This is identical to QFile::open(), with the one exception that the + Truncate mode flag is disallowed. Truncation would conflict with the + advisory file locking, since the file would be modified before the + write lock is obtained. If truncation is required, use resize(0) + after obtaining the write lock. + + Returns true if successful; otherwise false. + + \sa QFile::open(), QFile::resize() +*/ +bool QtLockedFile::open(OpenMode mode) { + if(mode & QIODevice::Truncate) { + qWarning("QtLockedFile::open(): Truncate mode not allowed."); + return false; + } + return QFile::open(mode); +} + +/*! + Returns \e true if this object has a in read or write lock; + otherwise returns \e false. + + \sa lockMode() +*/ +bool QtLockedFile::isLocked() const { + return m_lock_mode != NoLock; +} + +/*! + Returns the type of lock currently held by this object, or \e + QtLockedFile::NoLock. + + \sa isLocked() +*/ +QtLockedFile::LockMode QtLockedFile::lockMode() const { + return m_lock_mode; +} + +/*! + \fn bool QtLockedFile::lock(LockMode mode, bool block = true) + + Obtains a lock of type \a mode. The file must be opened before it + can be locked. + + If \a block is true, this function will block until the lock is + aquired. If \a block is false, this function returns \e false + immediately if the lock cannot be aquired. + + If this object already has a lock of type \a mode, this function + returns \e true immediately. If this object has a lock of a + different type than \a mode, the lock is first released and then a + new lock is obtained. + + This function returns \e true if, after it executes, the file is + locked by this object, and \e false otherwise. + + \sa unlock(), isLocked(), lockMode() +*/ + +/*! + \fn bool QtLockedFile::unlock() + + Releases a lock. + + If the object has no lock, this function returns immediately. + + This function returns \e true if, after it executes, the file is + not locked by this object, and \e false otherwise. + + \sa lock(), isLocked(), lockMode() +*/ + +/*! + \fn QtLockedFile::~QtLockedFile() + + Destroys the \e QtLockedFile object. If any locks were held, they + are released. +*/ diff --git a/src/singleapplication/qt-locked-file.h b/src/singleapplication/qt-locked-file.h new file mode 100644 index 00000000..332d648e --- /dev/null +++ b/src/singleapplication/qt-locked-file.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies) +** 2020 KylinSoft Co., Ltd. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTLOCKEDFILE_H +#define QTLOCKEDFILE_H + +#include +#ifdef Q_OS_WIN +#include +#endif + +#if defined(Q_OS_WIN) +# if !defined(QT_QTLOCKEDFILE_EXPORT) && !defined(QT_QTLOCKEDFILE_IMPORT) +# define QT_QTLOCKEDFILE_EXPORT +# elif defined(QT_QTLOCKEDFILE_IMPORT) +# if defined(QT_QTLOCKEDFILE_EXPORT) +# undef QT_QTLOCKEDFILE_EXPORT +# endif +# define QT_QTLOCKEDFILE_EXPORT __declspec(dllimport) +# elif defined(QT_QTLOCKEDFILE_EXPORT) +# undef QT_QTLOCKEDFILE_EXPORT +# define QT_QTLOCKEDFILE_EXPORT __declspec(dllexport) +# endif +#else +# define QT_QTLOCKEDFILE_EXPORT +#endif + +namespace QtLP_Private { + +class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile { +public: + enum LockMode { NoLock = 0, ReadLock, WriteLock }; + + QtLockedFile(); + QtLockedFile(const QString &name); + ~QtLockedFile(); + + bool open(OpenMode mode); + + bool lock(LockMode mode, bool block = true); + bool unlock(); + bool isLocked() const; + LockMode lockMode() const; + +private: +#ifdef Q_OS_WIN + Qt::HANDLE wmutex; + Qt::HANDLE rmutex; + QVector rmutexes; + QString mutexname; + + Qt::HANDLE getMutexHandle(int idx, bool doCreate); + bool waitMutex(Qt::HANDLE mutex, bool doBlock); + +#endif + LockMode m_lock_mode; +}; +} +#endif diff --git a/src/singleapplication/qt-single-application.cpp b/src/singleapplication/qt-single-application.cpp new file mode 100644 index 00000000..b924430c --- /dev/null +++ b/src/singleapplication/qt-single-application.cpp @@ -0,0 +1,353 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies) +** 2020 KylinSoft Co., Ltd. +** Contact: http://www.qt-project.org/legal +** +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +** +****************************************************************************/ + + +#include "qt-single-application.h" +#include "qt-local-peer.h" +#include +#include +#include +#include +#include +#include +#include "../mainwindow.h" + + +/*! + \class QtSingleApplication qtsingleapplication.h + \brief The QtSingleApplication class provides an API to detect and + communicate with running instances of an application. + + This class allows you to create applications where only one + instance should be running at a time. I.e., if the user tries to + launch another instance, the already running instance will be + activated instead. Another usecase is a client-server system, + where the first started instance will assume the role of server, + and the later instances will act as clients of that server. + + By default, the full path of the executable file is used to + determine whether two processes are instances of the same + application. You can also provide an explicit identifier string + that will be compared instead. + + The application should create the QtSingleApplication object early + in the startup phase, and call isRunning() to find out if another + instance of this application is already running. If isRunning() + returns false, it means that no other instance is running, and + this instance has assumed the role as the running instance. In + this case, the application should continue with the initialization + of the application user interface before entering the event loop + with exec(), as normal. + + The messageReceived() signal will be emitted when the running + application receives messages from another instance of the same + application. When a message is received it might be helpful to the + user to raise the application so that it becomes visible. To + facilitate this, QtSingleApplication provides the + setActivationWindow() function and the activateWindow() slot. + + If isRunning() returns true, another instance is already + running. It may be alerted to the fact that another instance has + started by using the sendMessage() function. Also data such as + startup parameters (e.g. the name of the file the user wanted this + new instance to open) can be passed to the running instance with + this function. Then, the application should terminate (or enter + client mode). + + If isRunning() returns true, but sendMessage() fails, that is an + indication that the running instance is frozen. + + Here's an example that shows how to convert an existing + application to use QtSingleApplication. It is very simple and does + not make use of all QtSingleApplication's functionality (see the + examples for that). + + \code + // Original + int main(int argc, char **argv) + { + QApplication app(argc, argv); + + MyMainWidget mmw; + mmw.show(); + return app.exec(); + } + + // Single instance + int main(int argc, char **argv) + { + QtSingleApplication app(argc, argv); + + if (app.isRunning()) + return !app.sendMessage(someDataString); + + MyMainWidget mmw; + app.setActivationWindow(&mmw); + mmw.show(); + return app.exec(); + } + \endcode + + Once this QtSingleApplication instance is destroyed (normally when + the process exits or crashes), when the user next attempts to run the + application this instance will not, of course, be encountered. The + next instance to call isRunning() or sendMessage() will assume the + role as the new running instance. + + For console (non-GUI) applications, QtSingleCoreApplication may be + used instead of this class, to avoid the dependency on the QtGui + library. + + \sa QtSingleCoreApplication +*/ + + +void QtSingleApplication::sysInit(const QString &appId) { + m_activateWindow = 0; + m_peer = new QtLocalPeer(this, appId); + connect(m_peer, &QtLocalPeer::messageReceived, this, &QtSingleApplication::messageReceived); +} + + +/*! + Creates a QtSingleApplication object. The application identifier + will be QCoreApplication::applicationFilePath(). \a argc, \a + argv, and \a GUIenabled are passed on to the QAppliation constructor. + + If you are creating a console application (i.e. setting \a + GUIenabled to false), you may consider using + QtSingleCoreApplication instead. +*/ + +QtSingleApplication::QtSingleApplication(int &argc, char **argv, bool GUIenabled) + : QApplication(argc, argv, GUIenabled) { + sysInit(); +} + + +/*! + Creates a QtSingleApplication object with the application + identifier \a appId. \a argc and \a argv are passed on to the + QAppliation constructor. +*/ + +QtSingleApplication::QtSingleApplication(const QString &appId, int &argc, char **argv) + : QApplication(argc, argv) { + sysInit(appId); +} + +#if QT_VERSION < 0x050000 + +/*! + Creates a QtSingleApplication object. The application identifier + will be QCoreApplication::applicationFilePath(). \a argc, \a + argv, and \a type are passed on to the QAppliation constructor. +*/ +QtSingleApplication::QtSingleApplication(int &argc, char **argv, Type type) + : QApplication(argc, argv, type) { + sysInit(); +} + + +# if defined(Q_WS_X11) +/*! + Special constructor for X11, ref. the documentation of + QApplication's corresponding constructor. The application identifier + will be QCoreApplication::applicationFilePath(). \a dpy, \a visual, + and \a cmap are passed on to the QApplication constructor. +*/ +QtSingleApplication::QtSingleApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE cmap) + : QApplication(dpy, visual, cmap) { + sysInit(); +} + +/*! + Special constructor for X11, ref. the documentation of + QApplication's corresponding constructor. The application identifier + will be QCoreApplication::applicationFilePath(). \a dpy, \a argc, \a + argv, \a visual, and \a cmap are passed on to the QApplication + constructor. +*/ +QtSingleApplication::QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap) + : QApplication(dpy, argc, argv, visual, cmap) { + sysInit(); +} + +/*! + Special constructor for X11, ref. the documentation of + QApplication's corresponding constructor. The application identifier + will be \a appId. \a dpy, \a argc, \a + argv, \a visual, and \a cmap are passed on to the QApplication + constructor. +*/ +QtSingleApplication::QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap) + : QApplication(dpy, argc, argv, visual, cmap) { + sysInit(appId); +} +# endif // Q_WS_X11 +#endif // QT_VERSION < 0x050000 + + +/*! + Returns true if another instance of this application is running; + otherwise false. + + This function does not find instances of this application that are + being run by a different user (on Windows: that are running in + another session). + + \sa sendMessage() +*/ + +bool QtSingleApplication::isRunning() { + return m_peer->isClient(); +} + + +/*! + Tries to send the text \a message to the currently running + instance. The QtSingleApplication object in the running instance + will emit the messageReceived() signal when it receives the + message. + + This function returns true if the message has been sent to, and + processed by, the current instance. If there is no instance + currently running, or if the running instance fails to process the + message within \a timeout milliseconds, this function return false. + + \sa isRunning(), messageReceived() +*/ +bool QtSingleApplication::sendMessage(const QString &message, int timeout) { + return m_peer->sendMessage(message, timeout); +} + + +/*! + Returns the application identifier. Two processes with the same + identifier will be regarded as instances of the same application. +*/ +QString QtSingleApplication::id() const { + return m_peer->applicationId(); +} + + +/*! + Sets the activation window of this application to \a aw. The + activation window is the widget that will be activated by + activateWindow(). This is typically the application's main window. + + If \a activateOnMessage is true (the default), the window will be + activated automatically every time a message is received, just prior + to the messageReceived() signal being emitted. + + \sa activateWindow(), messageReceived() +*/ + +void QtSingleApplication::setActivationWindow(QWidget* aw, bool activateOnMessage) { + m_activateWindow = aw; + if (activateOnMessage) + connect(m_peer, &QtLocalPeer::messageReceived, this, &QtSingleApplication::activateWindow); + else + disconnect(m_peer, &QtLocalPeer::messageReceived, this, &QtSingleApplication::activateWindow); +} + + +/*! + Returns the applications activation window if one has been set by + calling setActivationWindow(), otherwise returns 0. + + \sa setActivationWindow() +*/ +QWidget* QtSingleApplication::activationWindow() const { + return m_activateWindow; +} + + +/*! + De-minimizes, raises, and activates this application's activation window. + This function does nothing if no activation window has been set. + + This is a convenience function to show the user that this + application instance has been activated when he has tried to start + another instance. + + This function should typically be called in response to the + messageReceived() signal. By default, that will happen + automatically, if an activation window has been set. + + \sa setActivationWindow(), messageReceived(), initialize() +*/ +void QtSingleApplication::activateWindow() { + if (m_activateWindow) { + if(this->applicationState() & Qt::ApplicationInactive) + { + MainWindow* w=qobject_cast(m_activateWindow); + w->showMainwindow(); + m_activateWindow->setWindowState(m_activateWindow->windowState() & ~Qt::WindowMinimized); + m_activateWindow->raise(); + m_activateWindow->showNormal(); + m_activateWindow->activateWindow(); + } + else { + m_activateWindow->setWindowState(m_activateWindow->windowState() & Qt::WindowMinimized); + m_activateWindow->hide(); + } + } +} + + +/*! + \fn void QtSingleApplication::messageReceived(const QString& message) + + This signal is emitted when the current instance receives a \a + message from another instance of this application. + + \sa sendMessage(), setActivationWindow(), activateWindow() +*/ + + +/*! + \fn void QtSingleApplication::initialize(bool dummy = true) + + \obsolete +*/ diff --git a/src/singleapplication/qt-single-application.h b/src/singleapplication/qt-single-application.h new file mode 100644 index 00000000..084b9b7c --- /dev/null +++ b/src/singleapplication/qt-single-application.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies) +** 2020 KylinSoft Co., Ltd. +** Contact: http://www.qt-project.org/legal +** +** +** This file is part of the Qt Solutions component. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +** +****************************************************************************/ + +#ifndef QTSINGLEAPPLICATION_H +#define QTSINGLEAPPLICATION_H + +#include + +class QtLocalPeer; + +#if defined(Q_OS_WIN) +# if !defined(QT_QTSINGLEAPPLICATION_EXPORT) && !defined(QT_QTSINGLEAPPLICATION_IMPORT) +# define QT_QTSINGLEAPPLICATION_EXPORT +# elif defined(QT_QTSINGLEAPPLICATION_IMPORT) +# if defined(QT_QTSINGLEAPPLICATION_EXPORT) +# undef QT_QTSINGLEAPPLICATION_EXPORT +# endif +# define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllimport) +# elif defined(QT_QTSINGLEAPPLICATION_EXPORT) +# undef QT_QTSINGLEAPPLICATION_EXPORT +# define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllexport) +# endif +#else +# define QT_QTSINGLEAPPLICATION_EXPORT +#endif + +class QT_QTSINGLEAPPLICATION_EXPORT QtSingleApplication : public QApplication { + Q_OBJECT + +public: + QtSingleApplication(int &argc, char **argv, bool GUIenabled = true); + QtSingleApplication(const QString &id, int &argc, char **argv); +#if QT_VERSION < 0x050000 + QtSingleApplication(int &argc, char **argv, Type type); +# if defined(Q_WS_X11) + QtSingleApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0); + QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap = 0); + QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0); +# endif // Q_WS_X11 +#endif // QT_VERSION < 0x050000 + + bool isRunning(); + QString id() const; + + void setActivationWindow(QWidget* aw, bool activateOnMessage = true); + QWidget* activationWindow() const; + + // Obsolete: + void initialize(bool dummy = true) { + isRunning(); + Q_UNUSED(dummy) + } + +public Q_SLOTS: + bool sendMessage(const QString &message, int timeout = 5000); + void activateWindow(); + + +Q_SIGNALS: + void messageReceived(const QString &message); + + +private: + void sysInit(const QString &appId = QString()); + QtLocalPeer *m_peer; + QWidget *m_activateWindow; +}; + +#endif // QTSINGLEAPPLICATION_H diff --git a/src/singleapplication/qt-single-application.pri b/src/singleapplication/qt-single-application.pri new file mode 100644 index 00000000..0a4ca9ae --- /dev/null +++ b/src/singleapplication/qt-single-application.pri @@ -0,0 +1,27 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD +QT *= network +greaterThan(QT_MAJOR_VERSION, 4): QT *= widgets + +qtsingleapplication-uselib:!qtsingleapplication-buildlib { + LIBS += -L$$QTSINGLEAPPLICATION_LIBDIR -l$$QTSINGLEAPPLICATION_LIBNAME +} else { + SOURCES += + HEADERS += +} + +win32 { + contains(TEMPLATE, lib):contains(CONFIG, shared):DEFINES += QT_QTSINGLEAPPLICATION_EXPORT + else:qtsingleapplication-uselib:DEFINES += QT_QTSINGLEAPPLICATION_IMPORT +} + +HEADERS += \ + $$PWD/qt-local-peer.h \ + $$PWD/qt-locked-file.h \ + $$PWD/qt-single-application.h + +SOURCES += \ + $$PWD/qt-local-peer.cpp \ + $$PWD/qt-locked-file-unix.cpp \ + $$PWD/qt-single-application.cpp \ + $$PWD/qt-locked-file.cpp diff --git a/src/src.pro b/src/src.pro new file mode 100644 index 00000000..603befdd --- /dev/null +++ b/src/src.pro @@ -0,0 +1,68 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2018-10-19T15:29:47 +# +#------------------------------------------------- + +QT += core gui x11extras dbus KWindowSystem svg concurrent network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = kylin-nm +TEMPLATE = app + +CONFIG += c++14 qt warn_on link_pkgconfig +#CONFIG += release + +PKGCONFIG +=gio-2.0 glib-2.0 gio-unix-2.0 libnm libnma libsecret-1 gtk+-3.0 gsettings-qt libcap kysdk-qtwidgets + +INCLUDEPATH += /usr/include/KF5/NetworkManagerQt + +LIBS += -L/usr/lib/ -lgsettings-qt -lX11 -lKF5NetworkManagerQt -lukui-log4qt -lukui-com4c -lukui-com4cxx -lkysec +#LIBS += -lkysec +target.path = /usr/bin +target.source += $$TARGET +desktop.path = /etc/xdg/autostart/ +desktop.files = kylin-nm.desktop +gschema.files = org.ukui.kylin-nm.switch.gschema.xml +gschema.path = /usr/share/glib-2.0/schemas/ + +INSTALLS += target \ + desktop \ + gschema \ + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS WITHKYSEC + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +# QMAKE_CXXFLAGS += -Wno-unused-parameter +QMAKE_CPPFLAGS *= $(shell dpkg-buildflags --get CPPFLAGS) +QMAKE_CFLAGS *= $(shell dpkg-buildflags --get CFLAGS) +QMAKE_CXXFLAGS *= $(shell dpkg-buildflags --get CXXFLAGS) +QMAKE_LFLAGS *= $(shell dpkg-buildflags --get LDFLAGS) + +include(singleapplication/qt-single-application.pri) +include(backend/backend.pri) +include(frontend/frontend.pri) + +RESOURCES += \ + ../nmqrc.qrc + +SOURCES += \ + main.cpp + +unix { + UI_DIR = .ui + MOC_DIR = .moc + OBJECTS_DIR = .obj +} + +DISTFILES += \ + org.ukui.kylin-nm.switch.gschema.xml diff --git a/src/translations/kylin-nm_bo.qm b/src/translations/kylin-nm_bo.qm new file mode 100644 index 00000000..be651eed --- /dev/null +++ b/src/translations/kylin-nm_bo.qm @@ -0,0 +1 @@ + + + + + CreatNetPage + + + Connection Name + + + + + Ipv4Config + + + + + Address + + + + + Netmask + + + + + Default Gateway + + + + + Prefs DNS + + + + + Alternative DNS + + + + + Auto(DHCP) + + + + + Manual + + + + + DetailPage + + + Auto Connection + + + + + + SSID: + + + + + Copied successfully! + + + + + Copy all + + + + + Please input SSID: + + + + + + Protocol: + + + + + + Security Type: + + + + + + Hz: + + + + + + Chan: + + + + + + BandWidth: + + + + + + IPV6: + + + + + + IPV4: + + + + + + IPV4 Dns: + + + + + + Mac: + + + + + EnterpriseWlanDialog + + + Connect Enterprise WLAN + + + + + Cancel + + + + + Connect + + + + + Ipv4Page + + + Ipv4Config + + + + + Address + + + + + Netmask + + + + + Default Gateway + + + + + Prefs DNS + + + + + Alternative DNS + + + + + Auto(DHCP) + + + + + Manual + + + + + Ipv6Page + + + Ipv6Config + + + + + Address + + + + + Subnet prefix Length + + + + + Default Gateway + + + + + Prefs DNS + + + + + Alternative DNS + + + + + Auto(DHCP) + + + + + Manual + + + + + LanListItem + + + Not connected + + + + + Wired Device not carried + + + + + + Disconnect + + + + + + Connect + + + + + LanPage + + + No ethernet device avaliable + + + + + LAN + + + + + Activated LAN + + + + + Inactivated LAN + + + + + LAN Connected Successfully + + + + + LAN Disconnected Successfully + + + + + Wired Device not carried + + + + + ListItem + + + Kylin NM + + + + + kylin network applet desktop message + + + + + MainWindow + + + + kylin-nm + + + + + LAN + + + + + WLAN + + + + + Settings + + + + + Show MainWindow + + + + + NetDetail + + + Kylin NM + + + + + kylin network desktop message + + + + + Detail + + + + + Ipv4 + + + + + Ipv6 + + + + + Security + + + + + Confirm + + + + + Cancel + + + + + Forget this network + + + + + Add Lan Connect + + + + + connect hiddin wlan + + + + + + + None + + + + + + + Auto + + + + + start check ipv4 address conflict + + + + + start check ipv6 address conflict + + + + + + + ipv4 address conflict! + + + + + + ipv6 address conflict! + + + + + this wifi no support enterprise type + + + + + this wifi no support None type + + + + + this wifi no support WPA2 type + + + + + this wifi no support WPA3 type + + + + + OneConnForm + + + Form + + + + + OneLancForm + + + Form + + + + + SecurityPage + + + Security + + + + + + Password + + + + + EAP type + + + + + Identity + + + + + Domain + + + + + CA certficate + + + + + no need for CA certificate + + + + + User certificate + + + + + User private key + + + + + User key password + + + + + Ineer authentication + + + + + Usename + + + + + Ask pwd each query + + + + + + + + + + + + + None + + + + + WPA&WPA2 Personal + + + + + WPA&WPA2 Enterprise + + + + + WPA3 Personal + + + + + + + Choose from file... + + + + + + + Choose a CA certificate + + + + + + + CA Files (*.pem *.der *.p12 *.crt *.cer *.pfx) + + + + + TabPage + + + Current Device + + + + + Devices Closed! + + + + + Settings + + + + + Kylin NM + + + + + kylin network applet desktop message + + + + + WiFiConfigDialog + + + Dialog + + + + + WLAN Authentication + + + + + Input WLAN Information Please + + + + + WLAN ID: + + + + + WLAN Name: + + + + + Password: + + + + + Cancl + + + + + Ok + + + + + WlanListItem + + + Not connected + + + + + + Disconnect + + + + + + + Connect + + + + + + Forget + + + + + Auto Connect + + + + + WlanMoreItem + + + Add Others... + + + + + WlanPage + + + WLAN + + + + + Activated WLAN + + + + + Other WLAN + + + + + No wireless network card detected + + + + + WLAN Connected Successfully + + + + + + WLAN Disconnected Successfully + + + + diff --git a/translations/kylin-nm_tr.qm b/translations/kylin-nm_tr.qm new file mode 100644 index 00000000..07e2ca58 Binary files /dev/null and b/translations/kylin-nm_tr.qm differ diff --git a/translations/kylin-nm_tr.ts b/translations/kylin-nm_tr.ts new file mode 100644 index 00000000..82e901c0 --- /dev/null +++ b/translations/kylin-nm_tr.ts @@ -0,0 +1,2100 @@ + + + + + BackThread + + Confirm your WLAN password + WLAN parolasını doğrula + + + + ConfForm + + edit network + Ağı düzenle + + + LAN name: + LAN adı: + + + Method: + Yöntem: + + + Address: + Adres: + + + Netmask: + Netmask: + + + DNS 1: + DNS 1: + + + DNS 2: + DNS 2: + + + Edit Conn + Bağ. Düzenle + + + Auto(DHCP) + Oto(DHCP) + + + Manual + Elle + + + Cancel + İptal + + + Save + Kaydet + + + Ok + Tamam + + + Can not create new wired network for without wired card + Kablolu kart olmadan yeni kablolu ağ oluşturulamıyor + + + New network already created + Yeni ağ zaten oluşturuldu + + + New network settings already finished + Yeni ağ ayarları zaten tamamlandı + + + kylin network applet desktop message + Kylin ağ uygulaması masaüstü mesajı + + + Edit Network + Ağı Düzenle + + + Add Wired Network + Kablolu Ağ Ekle + + + create wired network successfully + Başarıyla kablolu ağ oluşturuldu + + + change configuration of wired network successfully + Kablolu ağın yapılandırmasını başarıyla değiştirildi + + + New settings already effective + Yeni ayarlar zaten etkili + + + + CreatNetPage + + + Connection Name + + + + + Ipv4Config + + + + + Address + + + + + Netmask + + + + + Default Gateway + + + + + Prefs DNS + + + + + Alternative DNS + + + + + Auto(DHCP) + Oto(DHCP) + + + + Manual + Elle + + + + DetailPage + + + Auto Connection + + + + + + SSID: + + + + + Copied successfully! + + + + + Copy all + + + + + Please input SSID: + + + + + + Protocol: + + + + + + Security Type: + + + + + + Hz: + + + + + + Chan: + + + + + + BandWidth: + + + + + + IPV6: + + + + + + IPV4: + + + + + + IPV4 Dns: + + + + + + Mac: + + + + + DlgHideWifi + + Add Hidden WLAN + Gizli WLAN Ekle + + + Connection + Bağlantı + + + WLAN name + WLAN adı + + + WLAN security + WLAN güvenlik + + + Cancel + İptal + + + Connect + Bağlantı + + + C_reate… + Oluştur... + + + None + Yok + + + Conn WLAN Success + WLAN Bağlantısı Başarılı + + + Confirm your WLAN password or usable of wireless card + Kablosuz şifrenizi veya kablosuz kart kullanılabilirliğini onaylayın + + + WPA & WPA2 Personal + WPA & WPA2 Kişisel + + + WEP 40/128-bit Key (Hex or ASCII) + WEP 40/128-bit Key (Hex veya ASCII) + + + WEP 128-bit Passphrase + WEP 128-bit Passphrase + + + Dynamic WEP (802.1X) + Dinamik WEP (802.1x) + + + WPA & WPA2 Enterprise + WPA & WPA2 Enterprise + + + Connect to Hidden WLAN Network + Gizli WLAN Ağına Bağlan + + + + DlgHideWifiEapFast + + Connect to Hidden WLAN Network + Gizli WLAN Ağına Bağlan + + + Add hidden WLAN + Gizli WLAN Ekle + + + Connection + Bağlantı: + + + Network name + Ağ adı + + + WLAN security + WLAN güvenliği + + + Authentication + Kimlik Doğrulama + + + Anonymous identity + Anonim kimlik + + + Allow automatic PAC pro_visioning + Otomatik PAC pro_visioning'e izin ver + + + PAC file + PAC dosyası + + + Inner authentication + İç kimlik doğrulama: + + + Username + Kullanıcı adı + + + Password + Parola + + + Cancel + İptal + + + Connect + Bağlan + + + C_reate… + Oluştur... + + + None + Yok + + + WPA & WPA2 Personal + WPA & WPA2 Kişisel + + + WEP 40/128-bit Key (Hex or ASCII) + WEP 40/128-bit Key (Hex veya ASCII) + + + WEP 128-bit Passphrase + WEP 128-bit Passphrase + + + Dynamic WEP (802.1X) + Dinamik WEP (802.1x) + + + WPA & WPA2 Enterprise + WPA & WPA2 Enterprise + + + Tunneled TLS + Tünelli TLS + + + Protected EAP (PEAP) + Korumalı EAP (PEAP) + + + Anonymous + Anonim + + + Authenticated + Doğrulanmış + + + Both + Her ikisi de + + + + DlgHideWifiEapLeap + + Connect to Hidden WLAN Network + Gizli WLAN ağına bağlan + + + Add hidden WLAN + Gizli WLAN ekle + + + Connection + Bağlantı: + + + Network name + Ağ adı: + + + WLAN security + WLAN güvenliği: + + + Authentication + Kimlik Doğrulama: + + + Username + Kullanıcı adı: + + + Password + Parola: + + + Cancel + 取消 + + + Connect + Bağlan + + + C_reate… + Oluştur... + + + None + Yok + + + WPA & WPA2 Personal + WPA & WPA2 Kişisel + + + WEP 40/128-bit Key (Hex or ASCII) + WEP 40/128-bit Key (Hex veya ASCII) + + + WEP 128-bit Passphrase + WEP 128-bit Passphrase + + + Dynamic WEP (802.1X) + Dinamik WEP (802.1x) + + + WPA & WPA2 Enterprise + WPA & WPA2 Enterprise + + + Tunneled TLS + Tünelli TLS + + + Protected EAP (PEAP) + Korumalı EAP (PEAP) + + + + DlgHideWifiEapPeap + + Connect to Hidden WLAN Network + Gizli WLAN Ağına Bağlan + + + Add hidden WLAN + Gizli WLAN ekle + + + Connection + Bağlantı: + + + Network name + Ağ adı: + + + WLAN security + WLAN güvenliği: + + + Authentication + Kimlik Doğrulama: + + + Anonymous identity + Anonim kimlik: + + + Domain + Domain: + + + CA certificate + CA sertifikası: + + + CA certificate password + CA sertifika şifresi: + + + No CA certificate is required + CA sertifikası gerekmez + + + PEAP version + PEAP sürümü: + + + Inner authentication + İç kimlik doğrulama: + + + Username + Kullanıcı adı: + + + Password + Parola: + + + Cancel + İptal + + + Connect + Bağlan + + + None + Yok + + + WPA & WPA2 Personal + WPA & WPA2 Kişisel + + + WEP 40/128-bit Key (Hex or ASCII) + WEP 40/128-bit Key (Hex veya ASCII) + + + WEP 128-bit Passphrase + WEP 128-bit Passphrase + + + Dynamic WEP (802.1X) + Dinamik WEP (802.1x) + + + WPA & WPA2 Enterprise + WPA & WPA2 Enterprise + + + Tunneled TLS + Tünelli TLS + + + Protected EAP (PEAP) + Korumalı EAP (PEAP) + + + Choose from file + Dosyadan seçin... + + + Automatic + Otomatik + + + Version 0 + Sürüm 0 + + + Version 1 + Sürüm 1 + + + + DlgHideWifiEapPwd + + Connect to Hidden WLAN Network + Gizli WLAN Ağına Bağlan + + + Add hidden WLAN + Gizli WLAN ekle + + + Connection + Bağlantı: + + + Network name + Ağ adı: + + + WLAN security + WLAN güvenliği: + + + Authentication + Kimlik Doğrulama: + + + Username + Kullanıcı adı: + + + Password + Parola: + + + Cancel + İptal + + + Connect + Bağlan + + + C_reate… + Oluştur... + + + None + Yok + + + WPA & WPA2 Personal + WPA & WPA2 Kişisel + + + WEP 40/128-bit Key (Hex or ASCII) + WEP 40/128-bit Key (Hex veya ASCII) + + + WEP 128-bit Passphrase + WEP 128-bit Passphrase + + + Dynamic WEP (802.1X) + Dinamik WEP (802.1x) + + + WPA & WPA2 Enterprise + WPA & WPA2 Enterprise + + + Tunneled TLS + Tünelli TLS + + + Protected EAP (PEAP) + Korumalı EAP (PEAP) + + + + DlgHideWifiEapTTLS + + Connect to Hidden WLAN Network + Gizli WLAN Ağına Bağlan + + + Add hidden WLAN + Gizli WLAN ekle + + + Connection + Bağlantı: + + + Network name + Ağ adı: + + + WLAN security + WLAN Güvenliği: + + + Authentication + Kimlik Doğrulama: + + + Anonymous identity + Anonim kimlik: + + + Domain + Domain: + + + CA certificate + CA Sertifikası: + + + CA certificate password + CA sertifika şifresi: + + + No CA certificate is required + CA sertifikası gerekmez + + + Inner authentication + İç kimlik doğrulama: + + + Username + Kullanıcı adı: + + + Password + Parola: + + + Cancel + İptal + + + Connect + Bağlan + + + C_reate… + Oluştur... + + + None + Yok + + + WPA & WPA2 Personal + WPA & WPA2 Kişisel + + + WEP 40/128-bit Key (Hex or ASCII) + WEP 40/128-bit Key (Hex veya ASCII) + + + WEP 128-bit Passphrase + WEP 128-bit Passphrase + + + Dynamic WEP (802.1X) + Dinamik WEP (802.1x) + + + WPA & WPA2 Enterprise + WPA & WPA2 Enterprise + + + Tunneled TLS + Tünelli TLS + + + Protected EAP (PEAP) + Korumalı EAP (PEAP) + + + Choose from file + Dosyadan seçiniz... + + + + DlgHideWifiEapTls + + Connect to Hidden WLAN Network + Gizli WLAN Ağına Bağlan + + + Add hidden WLAN + Gizli WLAN ekle + + + Connection + Bağlantı: + + + Network name + Ağ adı: + + + WLAN security + WLAN güvenliği: + + + Authentication + Kimlik Doğrulama: + + + Identity + Kimlik: + + + Domain + Domain: + + + CA certificate + CA sertifikası: + + + CA certificate password + CA sertifika şifresi: + + + No CA certificate is required + CA sertifikası gerekmez + + + User certificate + Kullanıcı sertifikası: + + + User certificate password + Kullanıcı sertifikası şifresi: + + + User private key + Kullanıcı özel anahtarı: + + + User key password + Kullanıcı anahtarı şifresi: + + + Cancel + İptal + + + Connect + Bağlan + + + C_reate… + Oluştur... + + + None + Yok + + + WPA & WPA2 Personal + WPA & WPA2 Kişisel + + + WEP 40/128-bit Key (Hex or ASCII) + WEP 40/128-bit Key (Hex veya ASCII) + + + WEP 128-bit Passphrase + WEP 128-bit Passphrase + + + Dynamic WEP (802.1X) + Dinamik WEP (802.1x) + + + WPA & WPA2 Enterprise + WPA & WPA2 Enterprise + + + Tunneled TLS + Tünelli TLS + + + Protected EAP (PEAP) + Korumalı EAP (PEAP) + + + Choose from file + Dosyadan seç... + + + + DlgHideWifiLeap + + Connect to Hidden WLAN Network + Gizli WLAN Ağına Bağlan + + + Add hidden WLAN + Gizli WLAN Ekle + + + Connection + Bağlantı + + + Network name + Ağ adı + + + WLAN security + WLAN Güvenlik + + + Username + Kullanıcı adı + + + Password + Parola + + + Cancel + İptal + + + Connect + Bağlan + + + C_reate… + Oluştur... + + + None + Yok + + + WPA & WPA2 Personal + WPA & WPA2 Kişisel + + + WEP 40/128-bit Key (Hex or ASCII) + WEP 40/128-bit Key (Hex veya ASCII) + + + WEP 128-bit Passphrase + WEP 128-bit Passphrase + + + Dynamic WEP (802.1X) + Dinamik WEP (802.1X) + + + WPA & WPA2 Enterprise + WPA & WPA2 Enterprise + + + + DlgHideWifiWep + + Connect to Hidden WLAN Network + Gizli WLAN Ağına Bağlan + + + Add hidden WLAN + Gizli WLAN Ekle + + + Connection + Bağlantı: + + + Network name + Ağ adı: + + + WLAN security + WLAN Güvenliği: + + + Key + Anahtar + + + WEP index + WEP index + + + Authentication + Kimlik Doğrulama: + + + Cancel + İptal + + + Connect + Bağlan + + + C_reate… + Oluştur... + + + None + Yok + + + WPA & WPA2 Personal + WPA & WPA2 Kişisel + + + WEP 40/128-bit Key (Hex or ASCII) + WEP 40/128-bit Key (Hex veya ASCII) + + + WEP 128-bit Passphrase + WEP 128-bit Passphrase + + + Dynamic WEP (802.1X) + Dinamik WEP (802.1x) + + + WPA & WPA2 Enterprise + WPA & WPA2 Enterprise + + + 1(default) + 1(default) + + + Open System + Sistemi aç + + + Shared Key + Paylaşılan Anahtar + + + + DlgHideWifiWpa + + Connect to Hidden WLAN Network + Gizli WLAN Ağına Bağlan + + + Add Hidden WLAN + Gizli WLAN Ekle + + + Connection + Bağlantı: + + + WLAN name + WLAN adı: + + + WLAN security + WLAN güvenlik: + + + Password + Parola: + + + Cancel + İptal + + + Connect + Bağlan + + + C_reate… + Oluştur... + + + None + Yok + + + Conn WLAN Success + WLAN Bağlantısı Başarılı + + + Confirm your WLAN password or usable of wireless card + Kablosuz şifrenizi veya kablosuz kart kullanılabilirliğini onaylayın + + + WPA & WPA2 Personal + WPA & WPA2 Kişisel + + + WPA & WPA2 Enterprise + WPA & WPA2 Enterprise + + + WEP 40/128-bit Key (Hex or ASCII) + WEP 40/128-bit Key (Hex veya ASCII) + + + Dynamic WEP (802.1X) + Dinamik WEP (802.1x) + + + + DlgHotspotCreate + + Create Hotspot + Etkin Nokta Oluştur + + + Network name + Ağ adı: + + + WLAN security + WLAN Güvenlik: + + + Password + Parola: + + + Cancel + İptal + + + Ok + Tamam + + + None + Yok + + + WPA & WPA2 Personal + WPA & WPA2 Kişisel + + + + EnterpriseWlanDialog + + + Connect Enterprise WLAN + + + + + Cancel + + + + + Connect + + + + + Ipv4Page + + + Ipv4Config + + + + + Address + + + + + Netmask + + + + + Default Gateway + + + + + Prefs DNS + + + + + Alternative DNS + + + + + Auto(DHCP) + Oto(DHCP) + + + + Manual + Elle + + + + Ipv6Page + + + Ipv6Config + + + + + Address + + + + + Subnet prefix Length + + + + + Default Gateway + + + + + Prefs DNS + + + + + Alternative DNS + + + + + Auto(DHCP) + Oto(DHCP) + + + + Manual + Elle + + + + KylinDBus + + kylin network applet desktop message + Kylin ağ uygulaması masaüstü mesajı + + + + LanListItem + + + Not connected + Bağlanamadı + + + + Wired Device not carried + + + + + + Disconnect + Bağlantıyı Kes + + + + + Connect + + + + + LanPage + + + No ethernet device avaliable + + + + + LAN + + + + + Activated LAN + + + + + Inactivated LAN + + + + + LAN Connected Successfully + + + + + LAN Disconnected Successfully + + + + + Wired Device not carried + + + + + ListItem + + + Kylin NM + + + + + kylin network applet desktop message + Kylin ağ uygulaması masaüstü mesajı + + + + MainWindow + + + + kylin-nm + + + + Network + + + + Advanced + Gelişmiş + + + Ethernet + Kablolu Ağ + + + Connect Hide Network + Gizli Ağı Bağlan + + + + LAN + + + + + WLAN + WLAN + + + + Settings + + + + Enabled + Aktif + + + Disabled + Pasif + + + HotSpot + HotSpot + + + + Show MainWindow + Ana Pencereyi Göster + + + Not connected + Bağlanamadı + + + Disconnected + Bağlantı Kesildi + + + No Other Wired Network Scheme + Başka Kablolu Ağ Düzeni Yok + + + No Other Wireless Network Scheme + Başka Kablosuz Ağ Düzeni Yok + + + Wired net is disconnected + Kablolu ağ bağlantısı kesildi + + + WLAN is disconnected + Kablosuz bağlantı kesildi + + + Confirm your WLAN password or usable of wireless card + Kablosuz şifrenizi veya kablosuz kart kullanılabilirliğini onaylayın + + + Confirm your WLAN password + WLAN parolasını doğrula + + + Ethernet Networks + Ethernet Ağları + + + New LAN + Yeni LAN + + + Hide WLAN + Gizli WLAN + + + No usable network in the list + Listede kullanılabilir ağ yok + + + WLAN Networks + WLAN Ağları + + + None + Yok + + + keep wired network switch is on before turning on wireless switch + Kablosuz anahtarı açmadan önce kablolu ağ anahtarını açık tut + + + please insert the wireless network adapter + Lütfen kablosuz ağ adaptörünü takın + + + Abnormal connection exist, program will delete it + Anormal bağlantı var, program onu ​​silecek + + + update WLAN list now, click again + Kablosuz listesini şimdi güncelle, tekrar tıkla + + + update WLAN list now + Kablosuz listesini şimdi güncelle + + + Conn Ethernet Success + Ethernet Bağlantısı Başarılı + + + Conn Ethernet Fail + Ethernet Bağlantısı Hatası + + + Conn WLAN Success + WLAN Bağlantısı Başarılı + + + + NetDetail + + + Kylin NM + + + + + kylin network desktop message + + + + + Detail + + + + + Ipv4 + + + + + Ipv6 + + + + + Security + + + + + Confirm + + + + + Cancel + + + + + Forget this network + + + + + Add Lan Connect + + + + + connect hiddin wlan + + + + + + + None + Yok + + + + + + Auto + Oto + + + + start check ipv4 address conflict + + + + + start check ipv6 address conflict + + + + + + + ipv4 address conflict! + + + + + + ipv6 address conflict! + + + + + this wifi no support enterprise type + + + + + this wifi no support None type + + + + + this wifi no support WPA2 type + + + + + this wifi no support WPA3 type + + + + + NotifySend + + Form + -- + + + + OldMainWindow + + Ethernet Networks + Ethernet Ağları + + + New LAN + Yeni LAN + + + WLAN Networks + WLAN Ağları + + + Hide WLAN + Gizli WLAN + + + No usable network in the list + Listede kullanılabilir ağ yok + + + Ethernet + Kablolu Ağ + + + HotSpot + HotSpot + + + Advanced + Gelişmiş + + + Show MainWindow + Ana Pencereyi Göster + + + Wired net is disconnected + Kablolu ağ bağlantısı kesildi + + + Not connected + Bağlanamadı + + + Disconnected + Bağlantı Kesildi + + + No Other Wired Network Scheme + Başka Kablolu Ağ Düzeni Yok + + + No Other Wireless Network Scheme + Başka Kablosuz Ağ Düzeni Yok + + + WLAN is disconnected + Kablosuz bağlantı kesildi + + + Conn Ethernet Success + Ethernet Bağlantısı Başarılı + + + Conn WLAN Success + WLAN Bağlantısı Başarılı + + + Confirm your WLAN password or usable of wireless card + Kablosuz şifrenizi veya kablosuz kart kullanılabilirliğini onaylayın + + + Confirm your WLAN password + WLAN parolasını doğrula + + + + OneConnForm + + + Form + -- + + + Input password + Parola gir + + + Config + Ayar + + + Connect + Bağlan + + + Disconnect + Bağlantıyı Kes + + + Input Password... + Parola gir... + + + Connect to Hidden WLAN Network + Gizli WLAN Ağına Bağlan + + + Public + Halka açık + + + Safe + Güvenli + + + Rate + Oran + + + None + Yok + + + WLAN Security: + WLAN güvenliği: + + + Sifnal: + Sinyal gücü: + + + MAC: + Fiziksel adres: + + + Conn WLAN Success + WLAN Bağlantısı Başarılı + + + Confirm your WLAN password or usable of wireless card + Kablosuz şifrenizi veya kablosuz kart kullanılabilirliğini onaylayın + + + Conn WLAN Failed + WLAN Bağlantısı Başarısız + + + + OneLancForm + + + Form + -- + + + Config + Ayar + + + Connect + Bağlan + + + Disconnect + Bağlantıyı Kes + + + Not connected + Bağlanamadı + + + Disconnected + Bağlantı Kesildi + + + Ethernet + Kablolu Ağ + + + No Configuration + Yapılandırma Yok + + + IPv4: + IPv4 adresi: + + + IPv6: + IPv6 adresi: + + + BandWidth: + Bant genişliği: + + + MAC: + Fiziksel adres: + + + Auto + Oto + + + + SecurityPage + + + Security + + + + + + Password + + + + + EAP type + + + + + Identity + Kimlik: + + + + Domain + Domain: + + + + CA certficate + + + + + no need for CA certificate + + + + + User certificate + Kullanıcı sertifikası: + + + + User private key + Kullanıcı özel anahtarı: + + + + User key password + Kullanıcı anahtarı şifresi: + + + + Ineer authentication + + + + + Usename + + + + + Ask pwd each query + + + + + + + + + + + + + None + Yok + + + + WPA&WPA2 Personal + + + + + WPA&WPA2 Enterprise + + + + + WPA3 Personal + + + + + + + Choose from file... + + + + + + + Choose a CA certificate + + + + + + + CA Files (*.pem *.der *.p12 *.crt *.cer *.pfx) + + + + + TabPage + + + Current Device + + + + + Devices Closed! + + + + + Settings + + + + + Kylin NM + + + + + kylin network applet desktop message + Kylin ağ uygulaması masaüstü mesajı + + + + Utils + + kylin network applet desktop message + Kylin ağ uygulaması masaüstü mesajı + + + + WiFiConfigDialog + + + Dialog + + + + + WLAN Authentication + + + + + Input WLAN Information Please + + + + + WLAN ID: + + + + + WLAN Name: + + + + + Password: + + + + + Cancl + + + + + Ok + Tamam + + + + WlanListItem + + + Not connected + Bağlanamadı + + + + + Disconnect + Bağlantıyı Kes + + + + + + Connect + + + + + + Forget + + + + + Auto Connect + + + + + WlanMoreItem + + + Add Others... + + + + + WlanPage + + + WLAN + WLAN + + + + Activated WLAN + + + + + Other WLAN + + + + + No wireless network card detected + + + + + WLAN Connected Successfully + + + + + + WLAN Disconnected Successfully + + + + + WpaWifiDialog + + Identity + Kimlik: + + + Domain + Domain: + + + None + Yok + + + diff --git a/translations/kylin-nm_zh_CN.qm b/translations/kylin-nm_zh_CN.qm new file mode 100644 index 00000000..8164222b Binary files /dev/null and b/translations/kylin-nm_zh_CN.qm differ diff --git a/translations/kylin-nm_zh_CN.ts b/translations/kylin-nm_zh_CN.ts new file mode 100644 index 00000000..6a9e870d --- /dev/null +++ b/translations/kylin-nm_zh_CN.ts @@ -0,0 +1,1180 @@ + + + + + ConfForm + + Manual + 手动 + + + Cancel + 取消 + + + kylin-nm + 网络工具 + + + kylin network applet desktop message + 网络提示消息 + + + Will check the IP address conflict + 正在检测ip地址冲突 + + + IPV4 address conflict, Please change IP + ip地址冲突,请更改ip + + + IPV6 address conflict, Please change IP + ip地址冲突,请更改ip {6 ?} + + + + CopyButton + + Copied successfully + 复制成功 + + + Copied successfully! + 复制成功! + + + Copy all + 复制全部 + + + + CreatNetPage + + + Connection Name + 网络名称 + + + + Ipv4Config + IPV4配置 + + + + Address + IPV4地址 + + + + Netmask + 子网掩码 + + + + Default Gateway + 默认网关 + + + + Prefs DNS + 首选DNS + + + + Alternative DNS + 备选DNS + + + + Auto(DHCP) + 自动(DHCP) + + + + Manual + 手动 + + + + DetailPage + + + Auto Connection + 自动连接 + + + + + SSID: + SSID: + + + + Copied successfully! + 复制成功! + + + + Copy all + 复制全部 + + + + Please input SSID: + 请输入SSID: + + + + + Protocol: + 协议: + + + + + Security Type: + 安全类型: + + + + + Hz: + 网络频带: + + + + + Chan: + 网络通道: + + + + + BandWidth: + 带宽: + + + + + IPV6: + 本地链接IPV6地址: + + + + + IPV4: + IPV4地址: + + + + + IPV4 Dns: + IPV4 DNS服务器: + + + + + Mac: + 物理地址: + + + + DlgHideWifi + + Cancel + 取消 + + + Connect + 连接 + + + None + + + + + DlgHideWifiEapFast + + Username + 用户名 + + + Password + 密钥 + + + Cancel + 取消 + + + Connect + 连接 + + + None + + + + + DlgHideWifiEapLeap + + Username + 用户名 + + + Password + 密钥 + + + Cancel + 取消 + + + Connect + 连接 + + + None + + + + + DlgHideWifiEapPeap + + Domain + + + + Username + 用户名 + + + Password + 密钥 + + + Cancel + 取消 + + + Connect + 连接 + + + None + + + + + DlgHideWifiEapPwd + + Username + 用户名 + + + Password + 密钥 + + + Cancel + 取消 + + + Connect + 连接 + + + None + + + + + DlgHideWifiEapTTLS + + Domain + + + + Username + 用户名 + + + Password + 密钥 + + + Cancel + 取消 + + + Connect + 连接 + + + None + + + + + DlgHideWifiEapTls + + Identity + 匿名身份 + + + Domain + + + + User certificate + 用户证书 + + + User private key + 用户私钥 + + + User key password + 用户密钥密码 + + + Cancel + 取消 + + + Connect + 连接 + + + None + + + + + DlgHideWifiLeap + + Username + 用户名 + + + Password + 密钥 + + + Cancel + 取消 + + + Connect + 连接 + + + None + + + + + DlgHideWifiWep + + Cancel + 取消 + + + Connect + 连接 + + + None + + + + + DlgHideWifiWpa + + Password + 密钥 + + + Cancel + 取消 + + + Connect + 连接 + + + None + + + + + EnterpriseWlanDialog + + + Connect Enterprise WLAN + 连接企业网 + + + Close + 关闭 + + + + Cancel + 取消 + + + + Connect + 连接 + + + + Ipv4Page + + + Ipv4Config + Ipv4配置 + + + + Address + 地址 + + + + Netmask + 子网掩码 + + + + Default Gateway + 默认网关 + + + + Prefs DNS + 首选DNS + + + + Alternative DNS + 备选DNS + + + + Auto(DHCP) + 自动 + + + + Manual + 手动 + + + + Ipv6Page + + + Ipv6Config + Ipv6配置 + + + + Address + 地址 + + + + Subnet prefix Length + 子网前缀长度 + + + + Default Gateway + 默认网关 + + + + Prefs DNS + 首选DNS + + + + Alternative DNS + 备选DNS + + + + Auto(DHCP) + 自动 + + + + Manual + 手动 + + + + LanListItem + + + Not connected + 未连接 + + + + Wired Device not carried + 未插入网线 + + + + + Disconnect + 断开 + + + + + Connect + 连接 + + + + LanPage + + + No ethernet device avaliable + 未检测到有线设备 + + + + LAN + 有线网络 + + + + Activated LAN + 我的网络 + + + + Inactivated LAN + 其他网络 + + + + LAN Disconnected Successfully + 有线网络已断开 + + + + Wired Device not carried + 未插入网线 + + + + LAN Connected Successfully + 有线网络已连接 + + + + ListItem + + + Kylin NM + 麒麟网络设置工具 + + + + kylin network applet desktop message + 网络提示消息 + + + + MainWindow + + + + kylin-nm + 网络工具 + + + + LAN + 有线网络 + 有线网络 + + + + WLAN + 无线局域网 + 无线局域网 + + + + Show MainWindow + 打开网络工具 + + + + Settings + 设置网络项 + 设置网络项 + + + + NetDetail + + + Kylin NM + 麒麟网络设置工具 + + + + kylin network desktop message + 网络提示消息 + + + + Detail + 详情 + + + + Ipv4 + Ipv4 + + + + Ipv6 + Ipv6 + + + + Security + 安全 + + + Close + 关闭 + + + + Confirm + 确定 + + + + Cancel + 取消 + + + + Forget this network + 忘记此网络 + + + + Add Lan Connect + 添加有线网络 + + + + connect hiddin wlan + 连接到隐藏WLAN + + + + + + None + + + + + + + Auto + 自动 + + + + start check ipv4 address conflict + 开始检测ipv4地址冲突 + + + + start check ipv6 address conflict + 开始检测ipv6地址冲突 + + + + + + ipv4 address conflict! + ipv4地址冲突! + + + + + ipv6 address conflict! + ipv6地址冲突! + + + + this wifi no support enterprise type + 此wifi不支持企业网类型 + + + + this wifi no support None type + 此wifi不支持空类型 + + + + this wifi no support WPA2 type + 此wifi不支持WPA2类型 + + + + this wifi no support WPA3 type + 此wifi不支持WPA3类型 + + + SSID: + SSID: + + + Protocol: + 协议: + + + Hz: + 网络频带: + + + Chan: + 网络通道: + + + BandWidth: + 带宽: + + + IPV4: + IPV4地址: + + + IPV4 Dns: + IPV4 DNS服务器: + + + IPV6: + 本地链接IPV6地址: + + + Mac: + 物理地址: + + + + OldMainWindow + + kylin-nm + 网络工具 + + + Show MainWindow + 打开网络工具 + + + Not connected + 未连接 + + + + OneConnForm + + + Form + + + + Connect + 连接 + + + Disconnect + 断开 + + + Cancel + 取消 + + + Forget + 忘记此网络 + + + None + + + + + OneLancForm + + + Form + + + + Connect + 连接 + + + Disconnect + 断开 + + + Cancel + 取消 + + + Not connected + 未连接 + + + + SecurityPage + + + Security + 安全性 + + + + + Password + 密钥 + + + + EAP type + EAP方法 + + + + Identity + 匿名身份 + + + + Domain + + + + + CA certficate + CA 证书 + + + + no need for CA certificate + 不需要CA证书 + + + + User certificate + 用户证书 + + + + User private key + 用户私钥 + + + + User key password + 用户密钥密码 + + + + Ineer authentication + 内部认证 + + + + Usename + 用户名 + + + Username + Usename + 用户名 + + + + Ask pwd each query + 每次询问密码 + + + + + + + + + + + + None + + + + + WPA&WPA2 Personal + WPA&WPA2 个人 + + + + WPA&WPA2 Enterprise + WPA&WPA2 企业 + + + + WPA3 Personal + WPA3 个人 + + + + + + Choose from file... + 从文件选择... + + + + + + Choose a CA certificate + 选择一个CA证书 + + + + + + CA Files (*.pem *.der *.p12 *.crt *.cer *.pfx) + CA 证书 (*.pem *.der *.p12 *.crt *.cer *.pfx) + + + + TabPage + + + Current Device + 当前网卡 + + + + Devices Closed! + 设备关闭! + + + + Settings + 网络设置 + + + + Kylin NM + 麒麟网络设置工具 + + + + kylin network applet desktop message + 网络提示消息 + + + + WiFiConfigDialog + + + Dialog + + + + + WLAN Authentication + + + + + Input WLAN Information Please + + + + + WLAN ID: + + + + + WLAN Name: + + + + + Password: + + + + + Cancl + + + + + Ok + + + + + WlanListItem + + + Not connected + 未连接 + + + + + Disconnect + 断开 + + + + + + Connect + 连接 + + + + + Forget + 忘记此网络 + + + + Auto Connect + 自动加入该网络 + + + + WlanMoreItem + + More... + 更多... + + + + Add Others... + 加入其他网络... + + + + WlanPage + + + WLAN + 无线局域网 + + + + No wireless network card detected + 未检测到无线网卡 + + + + Activated WLAN + 我的网络 + + + + Other WLAN + 其他网络 + + + More... + 更多... + + + + WLAN Connected Successfully + 无线网络已连接 + + + + + WLAN Disconnected Successfully + 无线网络已断开 + + + + WpaWifiDialog + + EAP type + EAP方法 + + + Username + 用户名 + + + Password + 密钥 + + + Ask pwd each query + 每次询问密码 + + + Cancel + 取消 + + + Connect + 连接 + + + None + + + + Choose from file... + 从文件选择... + + + Choose a CA certificate + 选择一个CA证书 + + + CA Files (*.pem *.der *.p12 *.crt *.cer *.pfx) + CA 证书 (*.pem *.der *.p12 *.crt *.cer *.pfx) + + + Identity + 匿名身份 + + + Domain + + + + no need for CA certificate + 不需要CA证书 + + +