ukui-bluetooth/0000755000175000017500000000000014205120476012457 5ustar fengfengukui-bluetooth/data/0000755000175000017500000000000014201160062013357 5ustar fengfengukui-bluetooth/data/org.ukui.bluetooth.gschema.xml0000644000175000017500000000324114201160062021256 0ustar fengfeng true bluetooth switch bluetooth switch "" File save path File save path "" Finally connect the device Last connected device saved [] List of paired devices Save a list of paired devices [] List of paired device address Save a list of paired device address [] List of adapter address Save a list of adapter address "" Save the Adapter used by default Save the Adapter used by default true Whether to display the icon in the tray Whether to display the icon in the tray ukui-bluetooth/data/ukui-bluetooth.desktop0000644000175000017500000000051614201160062017734 0ustar fengfeng[Desktop Entry] Type=Application Encoding=UTF-8 Name=ukui-bluetooth Name[zh_CN]=蓝牙 Comment=Simple bluetooth tool for ukui desktop environment Comment[zh_CN]=UKUI桌面环境简单的蓝牙工具 Exec=/usr/bin/ukui-bluetooth Icon=bluetooth StartupNotify=false OnlyShowIn=UKUI; X-UKUI-AutoRestart=true NoDisplay=true Terminal=false ukui-bluetooth/data/org.bluez.Agent1.conf0000644000175000017500000000155714201160062017263 0ustar fengfeng ukui-bluetooth/data/com.bluetooth.systemdbus.conf0000644000175000017500000000157214201160062021216 0ustar fengfeng ukui-bluetooth/data/com.bluetooth.systemdbus.policy0000644000175000017500000000120014201160062021554 0ustar fengfeng kylin os http://github.com/ukui/ ukui bluetooth system policy bluetooth auth_admin auth_admin auth_admin_keep ukui-bluetooth/data/com.bluetooth.systemdbus.service0000644000175000017500000000012714201160062021724 0ustar fengfeng[D-BUS Service] Name=com.bluetooth.systemdbus Exec=/usr/bin/bluetoothService User=root ukui-bluetooth/COPYING0000644000175000017500000004325414205120476013522 0ustar fengfeng GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. ukui-bluetooth/translations/0000755000175000017500000000000014201620261015171 5ustar fengfengukui-bluetooth/translations/ukui-bluetooth_zh_CN.ts0000644000175000017500000003514614201620261021613 0ustar fengfeng BluetoothFileTransferWidget Bluetooth file transfer 蓝牙文件传输 Transferring to " 正在传输至 " OK 确定 Cancel 取消 Successfully transmitted! 文件传输成功! Close 关闭 Transmission failed! 传输失败! DeviceSeleterWidget Select equipment 选择设备 No device currently available Please go to pair the device 当前没有可用的设备 请去配对设备 FeaturesWidget Bluetooth 蓝牙 Turn on bluetooth 开启蓝牙 Devices 设备 Disconnection 断开连接 Power 电量 Connect audio 连接音频 Connection 连接 bluetooth 蓝牙 Bluetooth Adapter Abnormal!!! 蓝牙适配器异常!!! Remove 移除 no bluetooth adapter! 没有蓝牙适配器! My Devices 我的设备 Send files 发送文件 No paired devices 没有已配对设备 Bluetooth settings 蓝牙设置 Bluetooth device “%1” disconnected successfully 蓝牙设备“%1”断开连接成功 Bluetooth device “%1” disconnected! 蓝牙设备“%1”失去连接! The connection with the Bluetooth device “%1” is successful! 与蓝牙设备“%1”连接成功! The connection with the Bluetooth device “%1” is failed! 与蓝牙设备“%1”连接失败! ukui-bluetooth 蓝牙 Bluetooth message 蓝牙消息 Bluetooth device " 与蓝牙设备 " " disconnected successfully " 断开成功 Disconnect from the Bluetooth device " 与蓝牙设备断开连接 " " " BlueTooth 蓝牙 Ukui-Bluetooth 蓝牙 Disconnect Error!!! 断开连接出错!!! Bluetooth device 蓝牙设备 disconnected! 断开连接!!! The connection with the Bluetooth device " 与蓝牙设备 " " is successful! " 连接成功! " failed! " 连接失败! Select the file to be sent 选择要发送的文件 All Files (*) 所有文件 (*) Turn off bluetooth 关闭蓝牙 FileReceivingPopupWidget Bluetooth file transfer 蓝牙文件传输 Bluetooth file transfer from " 蓝牙文件传输来自 " Cancel 取消 Accept 接收 View 查看 Sender canceled or transmission error 发送方取消或传输出错 PinCodeWidget Bluetooth pairing 蓝牙设备配对 Is it paired with " 正在等待 " " "接受连接请求 Is it paired with: 正在进行配对: Please make sure the number displayed on " 请确定 " " matches the number below. Please do not enter this code on any other accessories. " 上显示的数字与下面的数字匹配。请不要在任何其他配件上输入此代码。 Please enter the following PIN code on the bluetooth device %1 and press enter to pair ! 请在蓝牙设备 %1 上输入以下PIN码后按回车键进行配对 ! Accept 连接 Refush 取消 Pair 配对 Connection error !!! 连接出错 !!! Connection timed out !!! 连接超时 !!! Failed to pair with %1 !!! 和 %1 配对失败 !!! SwitchAction Bluetooth 蓝牙 ukui-bluetooth/translations/ukui-bluetooth_zh_CN.qm0000644000175000017500000000653414201620261021601 0ustar fengfengy:vep[WNN bvep[WS9M0N W(NOUQvN֑MNN QekdNx0S" matches the number below. Please do not enter this code on any other accessories. PinCodeWidgetcAccept PinCodeWidget rYYM[Bluetooth pairing PinCodeWidgetcQ Connection error !!! PinCodeWidgetT %1 M[Y1% !!!Failed to pair with %1 !!! PinCodeWidgetkcW(ۈLM[Is it paired with: PinCodeWidgetM[Pair PinCodeWidget (2020) ukui-bluetooth/man/ukui-bluetooth.10000644000175000017500000000120614201620261016264 0ustar fengfeng.\" Man Page for ukui-bluetooth .TH ukui-bluetooth 1 "August 05, 2020" .SH "NAME" bluetoothService \- command line binary for bluetoothService .SH "SYNOPSIS" .B ukui-bluetooth .SH "DESCRIPTION" .B ukui-bluetooth Manual for UKUI desktop environment A lightweight Bluetooth tool based on libkf5bluezqt6 .TP \fB --user\fR The user to be anthenticated. .TP \fB --device\fR The device for authentication. .SH "BUGS" .SS Should you encounter any bugs, they may be reported at: http://github.com/ukui/ukui-bluetooth/issues .SH "AUTHORS" .SS This Manual Page has been written for the UKUI Desktop Environment by tangguang (2020) ukui-bluetooth/ukui-bluetooth.pro0000644000175000017500000000172014201160062016150 0ustar fengfeng###################################################################### # Automatically generated by qmake (3.1) Thu Mar 4 22:02:53 2021 ###################################################################### TEMPLATE = subdirs INCLUDEPATH += . SUBDIRS += ukui-bluetooth \ service \ # The following define makes your compiler warn you 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 # 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 TRANSLATIONS += translations/ukui-bluetooth_zh_CN.ts ukui-bluetooth/ukui-bluetooth/0000755000175000017500000000000014205120337015433 5ustar fengfengukui-bluetooth/ukui-bluetooth/config/0000755000175000017500000000000014201647574016715 5ustar fengfengukui-bluetooth/ukui-bluetooth/config/xatom-helper.cpp0000644000175000017500000001401714201160062022007 0ustar fengfeng/* * 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 #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: } ukui-bluetooth/ukui-bluetooth/config/xatom-helper.h0000644000175000017500000000626714201160062021464 0ustar fengfeng/* * 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); bool isWindowDecorateBorderOnly(int winId); 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); ulong registerUKUICsdNetWmSupportAtom(); void unregisterUKUICsdNetWmSupportAtom(); ulong m_motifWMHintsAtom = 0l; ulong m_unityBorderRadiusAtom = 0l; ulong m_ukuiDecorationAtion = 0l; }; #endif // XATOMHELPER_H ukui-bluetooth/ukui-bluetooth/component/0000755000175000017500000000000014201620261017432 5ustar fengfengukui-bluetooth/ukui-bluetooth/component/switchbutton.cpp0000644000175000017500000001762114201160062022700 0ustar fengfeng/* -*- 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" SwitchButton::SwitchButton(QWidget *parent) : QWidget(parent) { // this->resize(QSize(52, 24)); this->setFixedSize(QSize(50, 24)); checked = false; hover = false; disabled = false; space = 4; // rectRadius = 5; step = width() / 40; startX = 0; endX= 0; timer = new QTimer(this); timer->setInterval(5); connect(timer, 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); drawBg(&painter); drawSlider(&painter); } 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::drawBg(QPainter *painter){ painter->save(); // painter->setPen(Qt::NoPen); if (disabled) { painter->setPen(Qt::NoPen); painter->setBrush(bgColorDisabled); } else { if (!checked){ painter->setPen(Qt::NoPen); painter->setBrush(bgColorOff); } else { painter->setPen(Qt::NoPen); painter->setBrush(bgColorOn); } } //circle out // QRect rect(space, space, width() - space * 2, height() - space * 2); // painter->drawRoundedRect(rect, rectRadius, rectRadius); //circle in QRect rect(0, 0, width(), height()); //半径为高度的一半 int radius = rect.height() / 2; //圆的宽度为高度 int circleWidth = rect.height(); QPainterPath path; path.moveTo(radius, rect.left()); path.arcTo(QRectF(rect.left(), rect.top(), circleWidth, circleWidth), 90, 180); path.lineTo(rect.width() - radius, rect.height()); path.arcTo(QRectF(rect.width() - rect.height(), rect.top(), circleWidth, circleWidth), 270, 180); path.lineTo(radius, rect.top()); painter->drawPath(path); painter->restore(); } void SwitchButton::drawSlider(QPainter *painter){ painter->save(); painter->setPen(Qt::NoPen); if (!disabled){ painter->setBrush(sliderColorEnabled); } else painter->setBrush(sliderColorDisabled); //circle out // QRect rect(0, 0, width() - space, height() - space); // int sliderwidth = rect.height(); // QRect sliderRect(startX, space / 2, sliderwidth, sliderwidth); // painter->drawEllipse(sliderRect); //circle in 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(startX + space, space, sliderWidth, sliderWidth); painter->drawEllipse(sliderRect); painter->restore(); } void SwitchButton::mousePressEvent(QMouseEvent *event){ if (timer->isActive()) { return ; } if (!disabled){ checked = !checked; emit checkedChanged(checked); step = width() / 40; if (checked){ //circle out // endX = width() - height() + space; //circle in endX = width() - height(); } else { endX = 0; } timer->start(); } else { endX = 0; } return QWidget::mousePressEvent(event); } void SwitchButton::resizeEvent(QResizeEvent *){ // step = width() / 40; if (checked){ //circle out // startX = width() - height() + space; //circle in startX = width() - height(); } else startX = 0; 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 (disabled) { return ; } if (checked) if (startX < endX){ startX = startX + step; } else { startX = endX; timer->stop(); } else { if (startX > endX){ startX = startX - step; } else { startX = endX; timer->stop(); } } update(); } void SwitchButton::setChecked(bool checked){ if (this->checked != checked){ this->checked = checked; emit checkedChanged(checked); update(); } step = width() / 40; if (checked){ //circle out // endX = width() - height() + space; //circle in endX = width() - height(); } else { endX = 0; } timer->start(); } bool SwitchButton::isChecked(){ return this->checked; } void SwitchButton::setDisabledFlag(bool value) { disabled = value; update(); } bool SwitchButton::getDisabledFlag() { return disabled; } ukui-bluetooth/ukui-bluetooth/component/switchbutton.h0000644000175000017500000000542414201620261022345 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2021 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); ~SwitchButton(); void setChecked(bool checked); 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; QColor bgColorOff; QColor bgColorOn; QColor bgHoverOnColor; QColor bgHoverOffColor; QColor bgColorDisabled; QColor sliderColorEnabled; QColor sliderColorDisabled; QColor rectColorEnabled; QColor rectColorDisabled; QGSettings *m_qtThemeSetting; QGSettings *m_gtkThemeSetting; int space; //滑块离背景间隔 int rectRadius; //圆角角度 int step; //移动步长 int startX; int endX; bool hover; QTimer * timer; private slots: void updatevalue(); Q_SIGNALS: void checkedChanged(bool checked); }; #endif // SWITCHBUTTON_H ukui-bluetooth/ukui-bluetooth/component/switchaction.cpp0000644000175000017500000000305214201620261022635 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2021 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 "switchaction.h" SwitchAction::SwitchAction(QWidget *parent) : QWidget(parent) { this->setFixedSize(240,40); QHBoxLayout *main_layout = new QHBoxLayout(this); main_layout->setSpacing(0); main_layout->setContentsMargins(32,0,16,0); QLabel *tip_label = new QLabel(tr("Bluetooth"),this); main_layout->addWidget(tip_label,1,Qt::AlignLeft|Qt::AlignVCenter); switch_btn = new SwitchButton(this); connect(switch_btn,&SwitchButton::checkedChanged,this,[=](bool value){ sendBtnStatus(value); }); main_layout->addWidget(switch_btn); } SwitchAction::~SwitchAction() { } void SwitchAction::setBtnStatus(bool value) { switch_btn->setChecked(value); } ukui-bluetooth/ukui-bluetooth/component/switchaction.h0000644000175000017500000000242414201620261022304 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2021 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 SWITCHACTION_H #define SWITCHACTION_H #include #include #include #include "switchbutton.h" class SwitchAction : public QWidget { Q_OBJECT public: explicit SwitchAction(QWidget *parent = nullptr); ~SwitchAction(); void setBtnStatus(bool value); signals: void sendBtnStatus(bool value); private: SwitchButton *switch_btn = nullptr; }; #endif // SWITCHACTION_H ukui-bluetooth/ukui-bluetooth/fileSend/0000755000175000017500000000000014201620261017161 5ustar fengfengukui-bluetooth/ukui-bluetooth/fileSend/deviceseleterwidget.h0000644000175000017500000000470214201620261023364 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2021 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 DEVICESELETERWIDGET_H #define DEVICESELETERWIDGET_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class DeviceSeleterWidget : public QWidget { Q_OBJECT public: explicit DeviceSeleterWidget(QWidget *parent = nullptr, QString dev = "", bool f = true); ~DeviceSeleterWidget(); void InitUI(); QString get_seleter_device(); QString get_seleter_dev_name(); signals: void sign_select(); private slots: void itemToolbuttonClicked(); void GSettingsChanges(const QString &key); private: QGSettings *GSettings = nullptr; QGSettings *settings = nullptr; private: BluezQt::Manager *m_manager = nullptr; QString select_dev; QString select_name = ""; bool flag = false; QList toolbutton_list; QToolButton *btn = nullptr; QLabel *Tiptop = nullptr; QScrollArea *m_scroll = nullptr; QWidget *dev_widget = nullptr; QVBoxLayout *device_list_layout = nullptr; }; #endif // DEVICESELETERWIDGET_H ukui-bluetooth/ukui-bluetooth/fileSend/deviceseleterwidget.cpp0000644000175000017500000001603414201620261023720 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2021 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 "deviceseleterwidget.h" DeviceSeleterWidget::DeviceSeleterWidget(QWidget *parent, QString dev, bool f): QWidget(parent), select_dev(dev) { if(QGSettings::isSchemaInstalled("org.ukui.style")){ GSettings = new QGSettings("org.ukui.style"); connect(GSettings,&QGSettings::changed,this,&DeviceSeleterWidget::GSettingsChanges); } if(QGSettings::isSchemaInstalled("org.ukui.bluetooth")){ settings = new QGSettings("org.ukui.bluetooth"); } this->resize(372,270); this->setAutoFillBackground(false); QPalette palette; if(GSettings->get("style-name").toString() == "ukui-default"){ palette.setColor(QPalette::Background,QColor(235,235,235)); }else{ palette.setColor(QPalette::Background,QColor(Qt::black)); } this->setPalette(palette); m_manager = new BluezQt::Manager(this); BluezQt::InitManagerJob *job = m_manager->init(); job->exec(); QVBoxLayout *main_layout = new QVBoxLayout(this); main_layout->setSpacing(5); main_layout->setContentsMargins(0,0,0,0); if(f){ QLabel *Tiptop = new QLabel(tr("Select equipment"),this); Tiptop->setFixedSize(200,25); Tiptop->setStyleSheet("QLabel{\ font-size: 18px;\ font-family: PingFangSC-Medium, PingFang SC;\ font-weight: 500;\ color: rgba(0, 0, 0, 0.85);\ line-height: 25px;}"); main_layout->addWidget(Tiptop); } m_scroll = new QScrollArea(this); m_scroll->setWidgetResizable(true); m_scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // m_scroll->setFixedSize(376,240); main_layout->addWidget(m_scroll); dev_widget = new QWidget(); m_scroll->setWidget(dev_widget); device_list_layout = new QVBoxLayout(dev_widget); device_list_layout->setSpacing(5); device_list_layout->setContentsMargins(8,8,8,8); dev_widget->setLayout(device_list_layout); InitUI(); } DeviceSeleterWidget::~DeviceSeleterWidget() { } void DeviceSeleterWidget::InitUI() { QList device_list = m_manager->adapterForAddress(settings->get("adapter-address").toString())->devices(); qDebug() << Q_FUNC_INFO << __LINE__ << device_list.size(); for(int i=0; i < device_list.size(); i++){ // qDebug() << Q_FUNC_INFO << device_list.at(i)->type() << device_list.at(i)->name(); if((device_list.at(i)->type() == BluezQt::Device::Phone)||(device_list.at(i)->type() == BluezQt::Device::Computer)){ if(device_list.at(i)->isPaired()){ QIcon icon; switch (device_list.at(i)->type()){ case BluezQt::Device::Type::Phone: icon = QIcon::fromTheme("phone-apple-iphone-symbolic"); break; case BluezQt::Device::Type::Computer: icon = QIcon::fromTheme("video-display-symbolic"); break; case BluezQt::Device::Type::Uncategorized: default: icon = QIcon::fromTheme("bluetooth-symbolic"); break; } QToolButton *item = new QToolButton(dev_widget); item->setFixedSize(this->width()-16,40); item->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); item->setStatusTip(device_list.at(i)->address()); item->setIcon(icon); item->setProperty("useIconHighlightEffect", 0x8); item->setText(" "+device_list.at(i)->name()); if(select_dev != ""){ if(device_list.at(i)->address() == select_dev){ item->setStyleSheet("QToolButton{background:lightgreen;color:black;}"); item->setChecked(true); btn = item; select_name = device_list.at(i)->name(); } } connect(item,&QToolButton::clicked,this,&DeviceSeleterWidget::itemToolbuttonClicked); toolbutton_list.append(item); device_list_layout->addWidget(item,Qt::AlignTop); // qDebug() << Q_FUNC_INFO << dev_widget->width() <name(); } } } if(toolbutton_list.size() == 0){ QLabel *tip_label = new QLabel(); tip_label->setFixedSize(this->width()-16,60); tip_label->setAlignment(Qt::AlignCenter); tip_label->setText(tr("No device currently available \n Please go to pair the device")); device_list_layout->addWidget(tip_label,Qt::AlignCenter); }else{ device_list_layout->addStretch(); } } QString DeviceSeleterWidget::get_seleter_device() { qDebug() << Q_FUNC_INFO; // for(int i = 0; i < toolbutton_list.size(); i++){ // toolbutton_list.at(i)->setChecked(false); // qDebug() << Q_FUNC_INFO << __LINE__ << toolbutton_list.at(i)->isChecked(); // if(toolbutton_list.at(i)->isChecked()){ // qDebug() << Q_FUNC_INFO <statusTip(); // return toolbutton_list.at(i)->statusTip(); // } // } return select_dev; } QString DeviceSeleterWidget::get_seleter_dev_name() { return select_name; } void DeviceSeleterWidget::itemToolbuttonClicked() { if(btn != nullptr || flag){ btn->setStyleSheet("QToolButton{background:#D9D9D9;color:black;}"); btn->setChecked(false); } QToolButton *p = qobject_cast(sender()); btn = p; p->setStyleSheet("QToolButton{background:lightgreen;color:black;}"); p->setChecked(true); select_dev = p->statusTip(); select_name = p->text(); emit sign_select(); if(flag == false) flag = true; } void DeviceSeleterWidget::GSettingsChanges(const QString &key) { QPalette palette; qDebug() << Q_FUNC_INFO << key; if(key == "styleName"){ if(GSettings->get("style-name").toString() == "ukui-default"){ palette.setColor(QPalette::Background,QColor(235,235,235)); }else{ palette.setColor(QPalette::Background,QColor(Qt::black)); } } this->setPalette(palette); } ukui-bluetooth/ukui-bluetooth/fileSend/bluetoothfiletransferwidget.cpp0000644000175000017500000003312214201620261025504 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2021 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 "bluetoothfiletransferwidget.h" #include "../config/xatom-helper.h" bool BluetoothFileTransferWidget::isShow = false; BluetoothFileTransferWidget::BluetoothFileTransferWidget(QString name, QString dev_address): // QWidget(parent), file_name(name) { isShow = true; send_state = _SEND_NONE; if(QGSettings::isSchemaInstalled("org.ukui.style")){ GSettings = new QGSettings("org.ukui.style"); connect(GSettings,&QGSettings::changed,this,&BluetoothFileTransferWidget::GSettingsChanges); } // =================添加窗管协议================================ MotifWmHints hints; hints.flags = MWM_HINTS_FUNCTIONS|MWM_HINTS_DECORATIONS; hints.functions = MWM_FUNC_ALL; hints.decorations = MWM_DECOR_BORDER; XAtomHelper::getInstance()->setWindowMotifHint(this->winId(), hints); // =========================================================== qDebug() << Q_FUNC_INFO << __LINE__; this->setFixedSize(440,498); // this->setWindowFlags(Qt::Dialog/*|Qt::FramelessWindowHint*/); this->setWindowIcon(QIcon::fromTheme("bluetooth")); this->setWindowTitle(tr("Bluetooth file transfer")); this->setAttribute(Qt::WA_DeleteOnClose); QPalette palette; if(GSettings->get("style-name").toString() == "ukui-default"){ palette.setColor(QPalette::Background,QColor(Qt::white)); }else{ palette.setColor(QPalette::Background,QColor(Qt::black)); } this->setPalette(palette); main_layout = new QVBoxLayout(this); main_layout->setSpacing(0); main_layout->setContentsMargins(8,4,4,0); QHBoxLayout *title_layout = new QHBoxLayout(); title_layout->setSpacing(8); title_layout->setContentsMargins(0,0,0,0); title_icon = new QLabel(this); title_icon->setPixmap(QIcon::fromTheme("preferences-system-bluetooth").pixmap(20,20)); title_icon->resize(20,20); title_layout->addWidget(title_icon); title_text = new QLabel(tr("Bluetooth file transfer"),this); title_text->resize(200,30); title_layout->addWidget(title_text); title_layout->addStretch(1); close_btn = new QPushButton(this); close_btn->setIcon(QIcon::fromTheme("window-close-symbolic")); close_btn->setProperty("isWindowButton", 0x2); close_btn->setProperty("useIconHighlightEffect", 0x8); close_btn->setFlat(true); close_btn->setFixedSize(30,30); connect(close_btn,&QPushButton::clicked,this,[=]{ emit this->close_the_pre_session(); this->close(); }); title_layout->addWidget(close_btn,1,Qt::AlignRight); main_layout->addLayout(title_layout); main_layout->addStretch(10); tip_text = new QLabel(tr("Transferring to \"")+dev_name+"\"",this); tip_text->setStyleSheet("QLabel{\ font-size: 18px;\ font-family: PingFangSC-Medium, PingFang SC;\ font-weight: 500;\ color: rgba(0, 0, 0, 0.85);\ line-height: 25px;}"); tip_text->setGeometry(32,58,400,25); tip_text->setVisible(false); Get_fie_type(); target_frame = new QFrame(this); target_frame->setGeometry(32,42,376,70); // target_frame->setStyleSheet("background:red;"); QHBoxLayout *target_layout = new QHBoxLayout(target_frame); target_layout->setSpacing(10); target_layout->setContentsMargins(0,0,0,0); QVBoxLayout *info_layout = new QVBoxLayout(); info_layout->setSpacing(0); info_layout->setContentsMargins(0,0,0,0); target_icon = new QLabel(target_frame); target_icon->setPixmap(file_icon.pixmap(40,40)); target_icon->resize(60,40); target_icon->setAlignment(Qt::AlignCenter); target_layout->addWidget(target_icon); target_size = new QLabel(file_size,target_frame); target_size->setAlignment(Qt::AlignTop); target_size->resize(200,20); QFontMetrics fontMetrics(target_size->font()); QString fileName = fontMetrics.elidedText(file_name.split("/").at(file_name.split("/").length()-1), Qt::ElideMiddle, 280); target_name = new QLabel(fileName,target_frame); target_name->setAlignment(Qt::AlignBottom); target_name->setToolTip(file_name); target_name->resize(290,35); info_layout->addStretch(); info_layout->addWidget(target_name,Qt::AlignCenter); info_layout->addWidget(target_size,Qt::AlignCenter); info_layout->addStretch(); target_layout->addLayout(info_layout); target_layout->addStretch(1); m_progressbar = new QProgressBar(this); m_progressbar->setOrientation(Qt::Horizontal); m_progressbar->setGeometry(32,175,376,10); m_progressbar->setTextVisible(false); m_progressbar->setVisible(false); dev_widget = new DeviceSeleterWidget(this,dev_address); dev_widget->resize(376,270); dev_widget->setGeometry(32,125,376,270); ok_btn = new QPushButton(tr("OK"),this); ok_btn->setFixedSize(120,36); ok_btn->setGeometry(288,435,120,36); if(dev_widget->get_seleter_device() == ""){ ok_btn->setEnabled(false); } connect(dev_widget, &DeviceSeleterWidget::sign_select, this, [=] { ok_btn->setEnabled(true); }); connect(ok_btn,&QPushButton::clicked,this,&BluetoothFileTransferWidget::onClicked_OK_Btn); cancel_btn = new QPushButton(tr("Cancel"),this); cancel_btn->setFixedSize(120,36); cancel_btn->setGeometry(288,221,120,36); cancel_btn->setVisible(false); connect(cancel_btn,&QPushButton::clicked,this,[=]{ emit this->close_the_pre_session(); this->close(); }); tranfer_status_icon = new QLabel(this); tranfer_status_icon->setFixedSize(64,64); tranfer_status_icon->setAlignment(Qt::AlignHCenter); tranfer_status_icon->setGeometry(188,77,64,64); tranfer_status_icon->setVisible(false); tranfer_status_text = new QLabel(this); tranfer_status_text->setGeometry(32,149,376,20); tranfer_status_text->setAlignment(Qt::AlignCenter); tranfer_status_text->setVisible(false); tranfer_status_text->setStyleSheet("QLabel{\ font-size: 14px;\ font-family: PingFangSC-Regular, PingFang SC;\ font-weight: 400;}"); } BluetoothFileTransferWidget::~BluetoothFileTransferWidget() { isShow = false; } void BluetoothFileTransferWidget::Get_fie_type() { GError *error; qDebug() << Q_FUNC_INFO << file_name; GFile *file = g_file_new_for_path(file_name.toStdString().c_str()); GFileInfo *file_info = g_file_query_info(file,"*",G_FILE_QUERY_INFO_NONE,NULL,&error); qDebug() << Q_FUNC_INFO << g_file_info_get_size(file_info) << g_file_info_get_content_type(file_info); file_size = g_format_size_full(g_file_info_get_size(file_info),G_FORMAT_SIZE_IEC_UNITS); QString str = g_file_info_get_content_type(file_info); if (str.split("/").at(0) == "image"){ file_icon = QIcon(file_name); if (file_icon.isNull()) { file_icon = QIcon::fromTheme("text"); } }else if (str.split("/").at(0) == "video") file_icon = QIcon::fromTheme("video-x-generic"); else if (str.split("/").at(0) == "audio" || str.split("/").at(0) == "application" || str.split("/").at(0) == "text"){ if (QIcon::hasThemeIcon(str.split("/").join("-"))) { file_icon = QIcon::fromTheme(str.split("/").join("-")); } else { file_icon = QIcon::fromTheme("text"); } }else file_icon = QIcon::fromTheme("text"); } void BluetoothFileTransferWidget::Initialize_and_start_animation() { this->resize(440,510); tip_text->setText(tr("Transferring to \"")+dev_widget->get_seleter_dev_name()+"\""); tip_text->update(); ok_btn->setVisible(false); main_animation_group = new QParallelAnimationGroup(this); QPropertyAnimation *this_action = new QPropertyAnimation(this,"geometry"); this_action->setDuration(300); this_action->setStartValue(this->geometry()); QRect this_rect = this->geometry(); this_rect.setHeight(300); this_action->setEndValue(this_rect); QPropertyAnimation *dev_widget_action = new QPropertyAnimation(dev_widget,"geometry"); dev_widget_action->setDuration(100); dev_widget_action->setStartValue(dev_widget->geometry()); QRect dev_widget_rect = dev_widget->geometry(); dev_widget_rect.setHeight(0); qDebug() << Q_FUNC_INFO << dev_widget_rect; dev_widget_action->setEndValue(dev_widget_rect); connect(dev_widget_action,&QPropertyAnimation::finished,this,[=]{ cancel_btn->setVisible(true); m_progressbar->setVisible(true); }); QPropertyAnimation *target_frame_action = new QPropertyAnimation(target_frame,"pos"); target_frame_action->setDuration(300); target_frame_action->setStartValue(target_frame->geometry().topLeft()); target_frame_action->setEndValue(QPoint(32,102)); connect(target_frame_action,&QPropertyAnimation::finished,this,[=]{ tip_text->setVisible(true); }); main_animation_group->addAnimation(this_action); main_animation_group->addAnimation(dev_widget_action); main_animation_group->addAnimation(target_frame_action); main_animation_group->start(); connect(main_animation_group,&QParallelAnimationGroup::finished,this,[=]{ this->setFixedSize(440,300); }); } void BluetoothFileTransferWidget::init_m_progressbar_value(quint64 value) { qDebug() << Q_FUNC_INFO << value; m_progressbar->setMinimum(0); m_progressbar->setMaximum(value); m_progressbar->setValue(0); } void BluetoothFileTransferWidget::get_transfer_status(QString status) { if(status == "complete"){ if(main_animation_group->state() == QAbstractAnimation::Running){ connect(main_animation_group,&QParallelAnimationGroup::finished,this,[=]{ tip_text->setVisible(false); target_frame->setVisible(false); m_progressbar->setVisible(false); }); } tip_text->setVisible(false); target_frame->setVisible(false); m_progressbar->setVisible(false); tranfer_status_icon->setPixmap(QIcon::fromTheme("ukui-dialog-success").pixmap(64,64)); tranfer_status_icon->setVisible(true); tranfer_status_text->setText(tr("Successfully transmitted!")); tranfer_status_text->setVisible(true); cancel_btn->setText(tr("Close")); this->send_state = _SEND_COMPLETE ; }else if(status == "active"){ this->send_state = _SENDING ; }else if(status == "error"){ tranfer_error(); this->send_state = _SEND_FAILURE ; } } void BluetoothFileTransferWidget::tranfer_error() { Initialize_and_start_animation(); if(main_animation_group->state() == QAbstractAnimation::Running){ connect(main_animation_group,&QParallelAnimationGroup::finished,this,[=]{ tip_text->setVisible(false); target_frame->setVisible(false); m_progressbar->setVisible(false); }); } tip_text->setVisible(false); target_frame->setVisible(false); m_progressbar->setVisible(false); tranfer_status_icon->setPixmap(QIcon::fromTheme("dialog-error").pixmap(64,64)); tranfer_status_icon->setVisible(true); tranfer_status_text->setText(tr("Transmission failed!")); tranfer_status_text->setVisible(true); cancel_btn->setText(tr("Close")); emit this->close_the_pre_session(); } int BluetoothFileTransferWidget::get_send_data_state() { return this->send_state; } void BluetoothFileTransferWidget::set_m_progressbar_value(quint64 value) { if(--active_flag <= 0) m_progressbar->setValue(value); } void BluetoothFileTransferWidget::GSettingsChanges(const QString &key) { qDebug() << Q_FUNC_INFO << key; if(key == "styleName"){ QPalette palette; if(GSettings->get("style-name").toString() == "ukui-default"){ palette.setColor(QPalette::Background,QColor(Qt::white)); target_icon->setProperty("setIconHighlightEffectDefaultColor", QColor(Qt::black)); target_icon->setProperty("useIconHighlightEffect", 0x10); }else{ palette.setColor(QPalette::Background,QColor(Qt::black)); target_icon->setProperty("setIconHighlightEffectDefaultColor", QColor(Qt::white)); target_icon->setProperty("useIconHighlightEffect", 0x10); } this->setPalette(palette); } } void BluetoothFileTransferWidget::onClicked_OK_Btn() { // qDebug() << Q_FUNC_INFO << this->rect() << this->geometry() << dev_widget->geometry() << ok_btn->geometry() << target_frame->geometry(); qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO << dev_widget->get_seleter_device(); if(dev_widget->get_seleter_device() == ""){ }else{ Initialize_and_start_animation(); emit this->sender_dev_name(dev_widget->get_seleter_device()); } } ukui-bluetooth/ukui-bluetooth/fileSend/bluetoothfiletransferwidget.h0000644000175000017500000000727714201620261025165 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2021 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 BLUETOOTHFILETRANSFERWIDGET_H #define BLUETOOTHFILETRANSFERWIDGET_H #include #include #include #include #include #include #include #include #include #include #include "deviceseleterwidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class DeviceSeleterWidget; enum FILE_TYPE{ Normal, mp3, mp4, image, }; class BluetoothFileTransferWidget : public QWidget { Q_OBJECT public: explicit BluetoothFileTransferWidget(QString name,QString dev_address = ""); ~BluetoothFileTransferWidget(); typedef enum _SEND_DATA_STATE { _SEND_NONE = 0, _SEND_COMPLETE, _SENDING, _SEND_FAILURE }SEND_DATA_STATE; static bool isShow; void Get_fie_type(); void Get_file_size(float); void Initialize_and_start_animation(); void init_m_progressbar_value(quint64); void get_transfer_status(QString); void tranfer_error(); int get_send_data_state(); signals: void sender_dev_name(QString); void close_the_pre_session(); public slots: void onClicked_OK_Btn(); void set_m_progressbar_value(quint64); void GSettingsChanges(const QString &key); private: QGSettings *GSettings = nullptr; QVBoxLayout *main_layout = nullptr; QLabel *tip_text = nullptr; QLabel *title_icon = nullptr; QLabel *title_text = nullptr; QFrame *target_frame = nullptr; QLabel *target_icon = nullptr; QLabel *target_name = nullptr; QLabel *target_size = nullptr ; QLabel *tranfer_status_icon = nullptr; QLabel *tranfer_status_text = nullptr; DeviceSeleterWidget *dev_widget = nullptr; QParallelAnimationGroup *main_animation_group = nullptr; QProgressBar *m_progressbar = nullptr; QPushButton *close_btn = nullptr; QPushButton *cancel_btn = nullptr; QPushButton *ok_btn = nullptr; QIcon file_icon; int active_flag = 2; QString file_name; QString file_size; QString dev_name; SEND_DATA_STATE send_state = _SEND_NONE; }; #endif // BLUETOOTHFILETRANSFERWIDGET_H ukui-bluetooth/ukui-bluetooth/daemon/0000755000175000017500000000000014201621044016673 5ustar fengfengukui-bluetooth/ukui-bluetooth/daemon/bluetoothdbus.cpp0000644000175000017500000000530714201620261022267 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2021 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 "bluetoothdbus.h" BluetoothDbus::BluetoothDbus(QObject *parent) { qDebug() << Q_FUNC_INFO << __LINE__; if(daemonIsNotRunning()){ QDBusConnection bus = QDBusConnection::sessionBus(); // 在session bus上注册名为"com.kylin_user_guide.hotel"的service if (!bus.registerService("org.ukui.bluetooth")) { //注意命名规则-和_ qDebug() << bus.lastError().message(); exit(1); } // "QDBusConnection::ExportAllSlots"表示把类Hotel的所有Slot都导出为这个Object的method qDebug() << Q_FUNC_INFO << __LINE__ << bus.registerObject("/org/ukui/bluetooth", "org.ukui.bluetooth", this,QDBusConnection::ExportAllSlots/*|QDBusConnection::ExportAllSignals*/); } } BluetoothDbus::~BluetoothDbus() { } int BluetoothDbus::daemonIsNotRunning() { QDBusConnection conn = QDBusConnection::sessionBus(); if (!conn.isConnected()) return 0; QDBusReply reply = conn.interface()->call("GetNameOwner", "org.ukui.bluetooth"); return reply.value() == ""; } void BluetoothDbus::connectToDevice(QString address) { qDebug() << Q_FUNC_INFO << address; emit this->ConnectTheSendingDevice(address); } void BluetoothDbus::disConnectToDevice(QString address) { qDebug() << Q_FUNC_INFO << address; emit this->DisconnectTheSendingDevice(address); } void BluetoothDbus::removeDevice(QString address) { qDebug() << Q_FUNC_INFO << address; emit this->RemoveTheSendingDevice(address); } QStringList BluetoothDbus::getPairedDevice() { } QString BluetoothDbus::getDevcieByAddress(QString) { } void BluetoothDbus::file_transfer(QStringList file) { qDebug() << Q_FUNC_INFO << file; emit this->sendTransferMesg(file); } void BluetoothDbus::Bluetooth_switch(bool value) { qDebug() << Q_FUNC_INFO ; emit this->switch_signals(value); } ukui-bluetooth/ukui-bluetooth/daemon/bluetoothdbus.h0000644000175000017500000000357314201620261021737 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2021 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 BLUETOOTHDBUS_H #define BLUETOOTHDBUS_H #include #include #include #include #include #include #include #include #include #include #include class BluetoothDbus : public QObject { Q_OBJECT public: explicit BluetoothDbus(QObject *parent = nullptr); virtual ~BluetoothDbus(); private: int daemonIsNotRunning(); signals: void ConnectTheSendingDevice(QString); void RemoveTheSendingDevice(QString); void DisconnectTheSendingDevice(QString); void sendTransferMesg(QStringList); void switch_signals(bool); public slots: void connectToDevice(QString); void disConnectToDevice(QString); void removeDevice(QString); QStringList getPairedDevice(); QString getDevcieByAddress(QString); void file_transfer(QStringList); void Bluetooth_switch(bool); }; #endif // BLUETOOTHDBUS_H ukui-bluetooth/ukui-bluetooth/pin/0000755000175000017500000000000014201623150016216 5ustar fengfengukui-bluetooth/ukui-bluetooth/pin/pincodewidget.cpp0000644000175000017500000002717114201620261021557 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2021 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 "pincodewidget.h" #include "../config/xatom-helper.h" PinCodeWidget::PinCodeWidget(QString name, QString pin, bool flag) : dev_name(name), PINCode(pin), show_flag(flag) { if(QGSettings::isSchemaInstalled("org.ukui.style")){ settings = new QGSettings("org.ukui.style"); connect(settings,&QGSettings::changed,this,&PinCodeWidget::GSettingsChanges); } // 添加窗管协议 MotifWmHints hints; hints.flags = MWM_HINTS_FUNCTIONS|MWM_HINTS_DECORATIONS; hints.functions = MWM_FUNC_ALL; hints.decorations = MWM_DECOR_BORDER; XAtomHelper::getInstance()->setWindowMotifHint(this->winId(), hints); // this->setWindowFlags(Qt::Dialog/*|Qt::FramelessWindowHint*/); this->setFixedSize(420,330); this->setWindowIcon(QIcon::fromTheme("bluetooth")); this->setWindowTitle(tr("Bluetooth pairing")); this->setAttribute(Qt::WA_DeleteOnClose); QList list = QGuiApplication::screens(); this->move(list.at(0)->size().width()/2-this->width()/2,list.at(0)->size().height()/2-this->height()/2); QPalette palette; if(settings->get("style-name").toString() == "ukui-default"){ palette.setColor(QPalette::Background,QColor(Qt::white)); }else{ palette.setColor(QPalette::Background,QColor(Qt::black)); } this->setPalette(palette); QString top_text = tr("Is it paired with:"); QString tip_text; QString name_test = dev_name_beyond_display_length(dev_name); qDebug () << Q_FUNC_INFO << name_test; if(show_flag) //tip_text = tr("Please make sure the number displayed on \"")+dev_name+tr("\" matches the number below. Please do not enter this code on any other accessories."); tip_text = tr("Please make sure the number displayed on \"")+name_test+tr("\" matches the number below. Please do not enter this code on any other accessories."); else tip_text = QString(tr("Please enter the following PIN code on the bluetooth device %1 and press enter to pair !")).arg(dev_name); top_label = new QLabel(top_text,this); top_label->setStyleSheet("QLabel{\ font-size: 18px;\ font-family: PingFangSC-Medium, PingFang SC;\ font-weight: 500;\ line-height: 25px;}"); top_label->setGeometry(32,48,334,25); tip_label = new QLabel(tip_text,this); tip_label->setStyleSheet("QLabel{\ font-size: 14px;\ font-family: PingFangSC-Regular, PingFang SC;\ font-weight: 400;\ line-height: 20px;}"); tip_label->setGeometry(32,89,359,60); tip_label->setWordWrap(true); PIN_label = new QLabel(PINCode,this); PIN_label->setStyleSheet("QLabel{\ font-size: 36px;\ font-family: ArialMT;\ line-height: 42px;}"); PIN_label->setGeometry(151,166,160,40); accept_btn = new QPushButton(tr("Accept"),this); accept_btn->setGeometry(160,255,120,36); connect(accept_btn,&QPushButton::clicked,this,&PinCodeWidget::onClick_accept_btn); refuse_btn = new QPushButton(tr("Refush"),this); refuse_btn->setGeometry(290,255,120,36); connect(refuse_btn,&QPushButton::clicked,this,&PinCodeWidget::onClick_refuse_btn); if(show_flag){ connect(accept_btn,&QPushButton::clicked,this,&PinCodeWidget::onClick_accept_btn); connect(refuse_btn,&QPushButton::clicked,this,&PinCodeWidget::onClick_refuse_btn); }else{ accept_btn->setVisible(false); refuse_btn->setVisible(false); } close_btn = new QPushButton(this); QIcon icon = QIcon::fromTheme("window-close-symbolic"); close_btn->setIcon(icon); close_btn->setProperty("isWindowButton", 0x2); close_btn->setProperty("useIconHighlightEffect", 0x8); // close_btn->setProperty("setIconHighlightEffectDefaultColor", QColor(Qt::white)); close_btn->setFlat(true); close_btn->setGeometry(386,4,30,30); connect(close_btn,&QPushButton::clicked,this,&PinCodeWidget::onClick_close_btn); } PinCodeWidget::PinCodeWidget(QString name, bool flag) : dev_name(name), show_flag(flag) { if(QGSettings::isSchemaInstalled("org.ukui.style")){ settings = new QGSettings("org.ukui.style"); connect(settings,&QGSettings::changed,this,&PinCodeWidget::GSettingsChanges); } // 添加窗管协议 MotifWmHints hints; hints.flags = MWM_HINTS_FUNCTIONS|MWM_HINTS_DECORATIONS; hints.functions = MWM_FUNC_ALL; hints.decorations = MWM_DECOR_BORDER; XAtomHelper::getInstance()->setWindowMotifHint(this->winId(), hints); // this->setWindowFlags(Qt::Dialog/*|Qt::FramelessWindowHint*/); this->setFixedSize(420,330); this->setWindowIcon(QIcon::fromTheme("bluetooth")); this->setWindowTitle(tr("Bluetooth pairing")); this->setAttribute(Qt::WA_DeleteOnClose); QList list = QGuiApplication::screens(); this->move(list.at(0)->size().width()/2-this->width()/2,list.at(0)->size().height()/2-this->height()/2); QPalette palette; if(settings->get("style-name").toString() == "ukui-default"){ palette.setColor(QPalette::Background,QColor(Qt::white)); }else{ palette.setColor(QPalette::Background,QColor(Qt::black)); } this->setPalette(palette); QString top_text = tr("Is it paired with:"); QString tip_text; QString name_test = dev_name_beyond_display_length(dev_name); qDebug () << Q_FUNC_INFO << name_test; tip_text = QString(tr("Please enter the following PIN code on the bluetooth device %1 and press enter to pair !")).arg(dev_name); top_label = new QLabel(top_text,this); top_label->setStyleSheet("QLabel{\ font-size: 18px;\ font-family: PingFangSC-Medium, PingFang SC;\ font-weight: 500;\ line-height: 25px;}"); top_label->setGeometry(32,48,334,25); tip_label = new QLabel(tip_text,this); tip_label->setStyleSheet("QLabel{\ font-size: 14px;\ font-family: PingFangSC-Regular, PingFang SC;\ font-weight: 400;\ line-height: 20px;}"); tip_label->setGeometry(32,89,359,60); tip_label->setWordWrap(true); PINCode_edit = new QLineEdit(this); PINCode_edit->setStyleSheet("QLabel{\ font-size: 36px;\ font-family: ArialMT;\ line-height: 42px;}"); PINCode_edit->setGeometry(151,166,160,40); accept_btn = new QPushButton(tr("Accept"),this); accept_btn->setGeometry(160,255,120,36); connect(accept_btn,&QPushButton::clicked,this,&PinCodeWidget::onClick_accept_btn); refuse_btn = new QPushButton(tr("Refush"),this); refuse_btn->setGeometry(290,255,120,36); connect(refuse_btn,&QPushButton::clicked,this,&PinCodeWidget::onClick_refuse_btn); // connect(accept_btn,&QPushButton::clicked,this,&PinCodeWidget::onClick_accept_btn); // connect(refuse_btn,&QPushButton::clicked,this,&PinCodeWidget::onClick_refuse_btn); close_btn = new QPushButton(this); QIcon icon = QIcon::fromTheme("window-close-symbolic"); close_btn->setIcon(icon); close_btn->setProperty("isWindowButton", 0x2); close_btn->setProperty("useIconHighlightEffect", 0x8); close_btn->setFlat(true); close_btn->setGeometry(386,4,30,30); connect(close_btn,&QPushButton::clicked,this,&PinCodeWidget::onClick_close_btn); } PinCodeWidget::~PinCodeWidget() { } QString PinCodeWidget::getEnteredPINCode() { return PINCode_edit->text(); } QString PinCodeWidget::dev_name_beyond_display_length(QString devName) { QString name ; if (devName.size() > 44) //一行只能显示44个字符 { name = devName.left(27); name.append("......"); name.append(devName.right(6)); } else { name = devName; } return name ; } QString PinCodeWidget::Insert_dev_name_newline(QString devName,int count) { qDebug () << Q_FUNC_INFO << devName < (45*(count+1)+((count==0)?0:count*2))) { devName = devName.insert((45*(count+1)+((count==0)?0:count*2)),"\n"); count++; devName = Insert_dev_name_newline(devName,count); } qDebug() << Q_FUNC_INFO << devName << count; return devName; } void PinCodeWidget::Connection_timed_out() { QMessageBox msgBox; msgBox.setParent(this); msgBox.setIcon(QMessageBox::Warning); msgBox.setWindowTitle(tr("Pair")); msgBox.setText(tr("Connection error !!!")); int ret = msgBox.exec(); if(ret){ if (show_flag) this->close(); else this->setHidden(true); } } void PinCodeWidget::pairFailureShow() { qDebug() << Q_FUNC_INFO << __LINE__; QMessageBox msgBox; msgBox.setParent(this); msgBox.setIcon(QMessageBox::Warning); msgBox.setWindowTitle(tr("Pair")); msgBox.setText(QString(tr("Failed to pair with %1 !!!").arg(dev_name))); int ret = msgBox.exec(); if(ret){ qDebug() << Q_FUNC_INFO << this << __LINE__; if (show_flag) this->close(); else this->setHidden(true); } } void PinCodeWidget::updateUIInfo(const QString &name, const QString &pin) { qDebug() << Q_FUNC_INFO << this->isActiveWindow() << __LINE__; PINCode = pin; PIN_label->setText(pin); PIN_label->update(); QString tip_text; if(show_flag) tip_text = tr("Please make sure the number displayed on \"")+name+tr("\" matches the number below. Please do not enter this code on any other accessories."); else tip_text = QString(tr("Please enter the following PIN code on the bluetooth device %1 and press enter to pair !")).arg(name); tip_label->setText(tip_text); tip_label->update(); if (!this->isActiveWindow()) this->setHidden(false); } void PinCodeWidget::onClick_close_btn(bool) { qDebug() << Q_FUNC_INFO << __LINE__; if (show_flag) { emit this->rejected(); this->close(); } else { this->setHidden(true); } } void PinCodeWidget::onClick_accept_btn(bool) { emit this->accepted(); this->close(); } void PinCodeWidget::onClick_refuse_btn(bool) { emit this->rejected(); this->close(); } void PinCodeWidget::GSettingsChanges(const QString &key) { QPalette palette; qDebug() << Q_FUNC_INFO << key; if(key == "styleName"){ if(settings->get("style-name").toString() == "ukui-default"){ palette.setColor(QPalette::Background,QColor(Qt::white)); }else{ palette.setColor(QPalette::Background,QColor(Qt::black)); } } this->setPalette(palette); } ukui-bluetooth/ukui-bluetooth/pin/pincodewidget.h0000644000175000017500000000464114201620261021221 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2021 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 PINCODEWIDGET_H #define PINCODEWIDGET_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class PinCodeWidget : public QWidget { Q_OBJECT public: explicit PinCodeWidget(QString name = "", QString pin = "", bool flag = true); PinCodeWidget(QString name = "", bool flag = true); ~PinCodeWidget(); void Connection_timed_out(); void pairFailureShow(); QString getEnteredPINCode(); void updateUIInfo(const QString &name,const QString &pin); private slots: void onClick_close_btn(bool); void onClick_accept_btn(bool); void onClick_refuse_btn(bool); void GSettingsChanges(const QString &key); signals: void accepted(); void rejected(); private: QGSettings *settings = nullptr; QLabel *PIN_label = nullptr; QLabel *tip_label = nullptr; QLabel *top_label = nullptr; QVBoxLayout *main_layout = nullptr; QPushButton *close_btn = nullptr; QPushButton *accept_btn = nullptr; QPushButton *refuse_btn = nullptr; QLineEdit *PINCode_edit = nullptr; QString dev_name; QString PINCode; bool show_flag; QString dev_name_beyond_display_length(QString devName); QString Insert_dev_name_newline(QString devName,int count); }; #endif // PINCODEWIDGET_H ukui-bluetooth/ukui-bluetooth/fileReceive/0000755000175000017500000000000014201620261017652 5ustar fengfengukui-bluetooth/ukui-bluetooth/fileReceive/filereceivingpopupwidget.h0000644000175000017500000000605514201620261025134 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2021 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 FILERECEIVINGPOPUPWIDGET_H #define FILERECEIVINGPOPUPWIDGET_H #include #include #include #include #include #include #include #include #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 FileReceivingPopupWidget : public QWidget { Q_OBJECT public: explicit FileReceivingPopupWidget(QString address = "", QString source = "", QString root = ""); ~FileReceivingPopupWidget(); QString getDeviceNameByAddress(QString); void configuration_transfer_progress_bar(quint64); void window_pop_up_animation(); bool move_file(); public slots: void OnClickedAcceptBtn(); void update_transfer_progress_bar(quint64); void file_transfer_completed(BluezQt::ObexTransfer::Status status); void GSettings_value_chanage(const QString &key); void GSettingsChanges(const QString &key); signals: void cancel(); void rejected(); void accepted(); private: QGSettings *StyleSettings = nullptr; QGSettings *settings = nullptr; QPushButton *close_btn = nullptr; QPushButton *cancel_btn = nullptr; QPushButton *accept_btn = nullptr; QPushButton *view_btn = nullptr; QLabel *icon_label = nullptr; QLabel *file_source = nullptr; QLabel *file_name = nullptr; QLabel *file_icon = nullptr; QProgressBar *transfer_progress = nullptr; QRect desktop; QString target_address; QString target_name; QString target_source; QString root_address; QString file_path; }; #endif // FILERECEIVINGPOPUPWIDGET_H ukui-bluetooth/ukui-bluetooth/fileReceive/filereceivingpopupwidget.cpp0000644000175000017500000003003214201620261025457 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2021 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 "filereceivingpopupwidget.h" #include "../config/xatom-helper.h" FileReceivingPopupWidget::FileReceivingPopupWidget(QString address, QString source, QString root): target_address(address), target_source(source), root_address(root) { if(QGSettings::isSchemaInstalled("org.ukui.style")){ StyleSettings = new QGSettings("org.ukui.style"); connect(StyleSettings,&QGSettings::changed,this,&FileReceivingPopupWidget::GSettingsChanges); } // 添加窗管协议 MotifWmHints hints; hints.flags = MWM_HINTS_FUNCTIONS|MWM_HINTS_DECORATIONS; hints.functions = MWM_FUNC_ALL; hints.decorations = MWM_DECOR_BORDER; XAtomHelper::getInstance()->setWindowMotifHint(this->winId(), hints); // this->setWindowFlags(Qt::Dialog/*|Qt::FramelessWindowHint*/); this->setFixedSize(440,250); this->setWindowIcon(QIcon::fromTheme("bluetooth")); this->setWindowTitle(tr("Bluetooth file transfer")); this->setAttribute(Qt::WA_DeleteOnClose); QPalette palette; if(StyleSettings->get("style-name").toString() == "ukui-default"){ palette.setColor(QPalette::Background,QColor(Qt::white)); }else{ palette.setColor(QPalette::Background,QColor(Qt::black)); } this->setPalette(palette); if(QGSettings::isSchemaInstalled("org.ukui.bluetooth")){ settings = new QGSettings("org.ukui.bluetooth"); file_path = settings->get("file-save-path").toString(); connect(settings, &QGSettings::changed,this,&FileReceivingPopupWidget::GSettings_value_chanage); }else{ file_path = QDir::homePath(); } QDesktopWidget *desktop_widget = QApplication::desktop(); desktop = desktop_widget->availableGeometry(); qDebug() << Q_FUNC_INFO << this->width() << this->height(); qDebug() << Q_FUNC_INFO <width() << desktop.bottom()-this->height(); this->move(QPoint(desktop.right()-this->width(),desktop.bottom()-this->height())); window_pop_up_animation(); close_btn = new QPushButton(this); close_btn->setIcon(QIcon::fromTheme("window-close-symbolic")); close_btn->setGeometry(406,4,30,30); close_btn->setProperty("isWindowButton", 0x2); close_btn->setProperty("useIconHighlightEffect", 0x8); close_btn->setFlat(true); connect(close_btn,&QPushButton::clicked,this,[=]{ emit this->rejected(); this->close(); }); icon_label = new QLabel(this); icon_label->setPixmap(QIcon::fromTheme("preferences-system-bluetooth").pixmap(20,20)); icon_label->setGeometry(28,51,20,20); target_name = getDeviceNameByAddress(target_address); file_source = new QLabel(tr("Bluetooth file transfer from \"")+target_name+"\"",this); file_source->setGeometry(56,35,350,50); file_source->setAlignment(Qt::AlignVCenter|Qt::AlignLeft); file_source->setWordWrap(true); file_source->setStyleSheet("QLabel{\ font-size: 18px;\ font-family: PingFangSC-Medium, PingFang SC;\ font-weight: 500;\ line-height: 25px;}"); file_icon = new QLabel(this); file_icon->setPixmap(QIcon::fromTheme("ukui-folder-documents-symbolic").pixmap(42,42)); file_icon->setAlignment(Qt::AlignCenter); file_icon->setGeometry(28,95,65,42); QFontMetrics fontMetrics(file_source->font()); QString fileName = fontMetrics.elidedText(target_source, Qt::ElideMiddle, 280); file_name = new QLabel(fileName,this); file_name->setToolTip(target_source); file_name->setGeometry(101,87,293,60); file_name->setAlignment(Qt::AlignVCenter|Qt::AlignLeft); file_name->setWordWrap(true); transfer_progress = new QProgressBar(this); transfer_progress->setGeometry(29,147,376,6); transfer_progress->setTextVisible(false); transfer_progress->setVisible(false); cancel_btn = new QPushButton(tr("Cancel"),this); cancel_btn->setGeometry(152,177,120,36); connect(cancel_btn,&QPushButton::clicked,this,[=]{ emit this->rejected(); this->close(); }); accept_btn = new QPushButton(tr("Accept"),this); accept_btn->setGeometry(288,177,120,36); connect(accept_btn,&QPushButton::clicked,this,[=]{ OnClickedAcceptBtn(); }); view_btn = new QPushButton(tr("View"),this); view_btn->setGeometry(288,177,120,36); view_btn->setVisible(false); } FileReceivingPopupWidget::~FileReceivingPopupWidget() { delete settings; } QString FileReceivingPopupWidget::getDeviceNameByAddress(QString address) { qDebug() << Q_FUNC_INFO << __LINE__; BluezQt::Manager *manager = new BluezQt::Manager(this); BluezQt::InitManagerJob *job = manager->init(); job->exec(); BluezQt::AdapterPtr adapter = manager->adapterForAddress(root_address); // BluezQt::AdapterPtr adapter = manager->usableAdapter(); QString name = adapter->deviceForAddress(address)->name(); qDebug() << Q_FUNC_INFO << __LINE__; return name; } void FileReceivingPopupWidget::configuration_transfer_progress_bar(quint64 value) { transfer_progress->setMinimum(0); transfer_progress->setMaximum(value); transfer_progress->setValue(0); } void FileReceivingPopupWidget::window_pop_up_animation() { qDebug() << Q_FUNC_INFO << desktop << desktop.right() << desktop.bottom() <geometry(); // QPropertyAnimation *window_action = new QPropertyAnimation(this,"geometry"); // window_action->setDuration(100); // QRect this_rect = this->rect(); // this_rect.setHeight(0); // this_rect.setWidth(0); // window_action->setStartValue(QRect(desktop.right()-1,desktop.bottom()-this->height(),desktop.right(),desktop.bottom())); // window_action->setEndValue(QRect(desktop.right()-this->width(),desktop.bottom()-this->height(),desktop.right(),desktop.bottom())); // window_action->setStartValue(QPoint(desktop.right()-1,desktop.bottom()-this->height())); // window_action->setEndValue(QPoint(desktop.right()-this->width(),desktop.bottom()-this->height())); // qDebug() << Q_FUNC_INFO << this_rect << this->geometry() << QRect(desktop.right()-1,desktop.bottom()-this->height(),desktop.right(),desktop.bottom()) <width(),desktop.bottom()-this->height(),desktop.right(),desktop.bottom()); // window_action->start(); } bool FileReceivingPopupWidget::move_file() { QString s = QDir::homePath()+"/.cache/obexd/"+target_source; QString d = file_path+"/"+target_source; if(!QFile::exists(file_path)){ int status; status = mkdir(file_path.toStdString().c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); qDebug() << Q_FUNC_INFO << status; if(status == -1) return -1; } GError *error; GFile *source = g_file_new_for_path(s.toStdString().c_str()); GFile *destination = g_file_new_for_path(d.toStdString().c_str()); bool flag = g_file_move(source,destination,G_FILE_COPY_OVERWRITE,NULL,NULL,NULL,&error); qDebug() << Q_FUNC_INFO << "move file" << "target_path =" << s << " source_path =" << d << "flag =" << flag; return flag; } void FileReceivingPopupWidget::OnClickedAcceptBtn() { transfer_progress->setVisible(true); accept_btn->setVisible(false); QParallelAnimationGroup *actions = new QParallelAnimationGroup(this); QPropertyAnimation *progress_action = new QPropertyAnimation(transfer_progress,"geometry"); QRect transfer_progress_rect = transfer_progress->geometry(); transfer_progress_rect.setWidth(0); progress_action->setStartValue(transfer_progress_rect); progress_action->setEndValue(transfer_progress->geometry()); progress_action->setDuration(200); QPropertyAnimation *cancel_btn_action = new QPropertyAnimation(cancel_btn,"pos"); cancel_btn_action->setStartValue(cancel_btn->geometry().topLeft()); cancel_btn_action->setEndValue(QPoint(288,177)); cancel_btn_action->setDuration(100); actions->addAnimation(progress_action); actions->addAnimation(cancel_btn_action); actions->start(); connect(actions,&QParallelAnimationGroup::finished,this,[=]{ this->accepted(); }); } void FileReceivingPopupWidget::update_transfer_progress_bar(quint64 value) { transfer_progress->setValue(value); transfer_progress->repaint(); } void FileReceivingPopupWidget::file_transfer_completed(BluezQt::ObexTransfer::Status status) { qDebug() << Q_FUNC_INFO <disconnect(); cancel_btn->connect(cancel_btn,&QPushButton::clicked,this,[=]{ emit this->cancel(); this->close(); }); close_btn->disconnect(); close_btn->connect(close_btn,&QPushButton::clicked,this,[=]{ emit this->cancel(); this->close(); }); }else if(status == BluezQt::ObexTransfer::Complete){ close_btn->disconnect(); close_btn->connect(close_btn,&QPushButton::clicked,this,[=]{ this->close(); }); cancel_btn->setVisible(false); // bool x= QFile::rename(QDir::homePath()+"/.cache/obexd/"+target_source,file_path+"/"+target_source); bool x = move_file(); // view_btn->setVisible(true); qDebug() << Q_FUNC_INFO << __LINE__ << x; if(x){ // connect(view_btn,&QPushButton::clicked,this,[=]{ QProcess *process = new QProcess(this); QString cmd = "peony"; QStringList arg; qDebug() << Q_FUNC_INFO; arg << "--show-items" <startDetached(cmd,arg); this->close(); // }); } }else if(status == BluezQt::ObexTransfer::Error){ accept_btn->setVisible(false); close_btn->disconnect(); close_btn->connect(close_btn,&QPushButton::clicked,this,[=]{ this->close(); }); cancel_btn->setVisible(false); QFrame *warn_frame = new QFrame(this); warn_frame->setGeometry(0,176,440,30); QHBoxLayout *warn_layout = new QHBoxLayout(warn_frame); warn_layout->setSpacing(10); warn_layout->setContentsMargins(0,0,0,0); QLabel *warn_icon = new QLabel(this); warn_icon->setPixmap(QIcon::fromTheme("dialog-warning").pixmap(30,30)); QLabel *warn_text = new QLabel(tr("Sender canceled or transmission error"),this); warn_text->setAlignment(Qt::AlignVCenter); warn_layout->addStretch(); warn_layout->addWidget(warn_icon); warn_layout->addWidget(warn_text); warn_layout->addStretch(); warn_frame->show(); } } void FileReceivingPopupWidget::GSettings_value_chanage(const QString &key) { if(key == "file-save-path"){ file_path = settings->get("file-save-path").toString(); } } void FileReceivingPopupWidget::GSettingsChanges(const QString &key) { qDebug() << Q_FUNC_INFO << key; if(key == "styleName"){ QPalette palette; if(StyleSettings->get("style-name").toString() == "ukui-default"){ palette.setColor(QPalette::Background,QColor(Qt::white)); }else{ palette.setColor(QPalette::Background,QColor(Qt::black)); } this->setPalette(palette); } } ukui-bluetooth/ukui-bluetooth/qtsingleapplication/0000755000175000017500000000000014201647500021507 5ustar fengfengukui-bluetooth/ukui-bluetooth/qtsingleapplication/qtsinglecoreapplication.h0000644000175000017500000000502514201160062026576 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** 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 QTSINGLECOREAPPLICATION_H #define QTSINGLECOREAPPLICATION_H #include class QtLocalPeer; class QtSingleCoreApplication : public QCoreApplication { Q_OBJECT public: QtSingleCoreApplication(int &argc, char **argv); QtSingleCoreApplication(const QString &id, int &argc, char **argv); bool isRunning(); QString id() const; public Q_SLOTS: bool sendMessage(const QString &message, int timeout = 5000); Q_SIGNALS: void messageReceived(const QString &message); private: QtLocalPeer* peer; }; #endif // QTSINGLECOREAPPLICATION_H ukui-bluetooth/ukui-bluetooth/qtsingleapplication/qtlockedfile.cpp0000644000175000017500000001374214201160062024661 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** 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 "qtlockedfile.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. */ ukui-bluetooth/ukui-bluetooth/qtsingleapplication/qtlocalpeer.cpp0000644000175000017500000001543414201160062024526 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** 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 "qtlocalpeer.h" #include #include #include #if defined(Q_OS_WIN) #include #include typedef BOOL(WINAPI*PProcessIdToSessionId)(DWORD,DWORD*); static PProcessIdToSessionId pProcessIdToSessionId = 0; #endif #if defined(Q_OS_UNIX) #include #include #include #endif namespace QtLP_Private { #include "qtlockedfile.cpp" #if defined(Q_OS_WIN) #include "qtlockedfile_win.cpp" #else #include "qtlockedfile_unix.cpp" #endif } 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"); 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; 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, SIGNAL(newConnection()), SLOT(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; } void QtLocalPeer::receiveConnection() { QLocalSocket* socket = server->nextPendingConnection(); 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; emit messageReceived(message); //### (might take a long time to return) } ukui-bluetooth/ukui-bluetooth/qtsingleapplication/qtlocalpeer.h0000644000175000017500000000520514201160062024166 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** 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 "qtlockedfile.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 ukui-bluetooth/ukui-bluetooth/qtsingleapplication/qtlockedfile_win.cpp0000644000175000017500000001466114201160062025537 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** 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 "qtlockedfile.h" #include #include #define MUTEX_PREFIX "QtLockedFile mutex " // Maximum number of concurrent read locks. Must not be greater than MAXIMUM_WAIT_OBJECTS #define MAX_READERS MAXIMUM_WAIT_OBJECTS #if QT_VERSION >= 0x050000 #define QT_WA(unicode, ansi) unicode #endif Qt::HANDLE QtLockedFile::getMutexHandle(int idx, bool doCreate) { if (mutexname.isEmpty()) { QFileInfo fi(*this); mutexname = QString::fromLatin1(MUTEX_PREFIX) + fi.absoluteFilePath().toLower(); } QString mname(mutexname); if (idx >= 0) mname += QString::number(idx); Qt::HANDLE mutex; if (doCreate) { QT_WA( { mutex = CreateMutexW(NULL, FALSE, (TCHAR*)mname.utf16()); }, { mutex = CreateMutexA(NULL, FALSE, mname.toLocal8Bit().constData()); } ); if (!mutex) { qErrnoWarning("QtLockedFile::lock(): CreateMutex failed"); return 0; } } else { QT_WA( { mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (TCHAR*)mname.utf16()); }, { mutex = OpenMutexA(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, mname.toLocal8Bit().constData()); } ); if (!mutex) { if (GetLastError() != ERROR_FILE_NOT_FOUND) qErrnoWarning("QtLockedFile::lock(): OpenMutex failed"); return 0; } } return mutex; } bool QtLockedFile::waitMutex(Qt::HANDLE mutex, bool doBlock) { Q_ASSERT(mutex); DWORD res = WaitForSingleObject(mutex, doBlock ? INFINITE : 0); switch (res) { case WAIT_OBJECT_0: case WAIT_ABANDONED: return true; break; case WAIT_TIMEOUT: break; default: qErrnoWarning("QtLockedFile::lock(): WaitForSingleObject failed"); } return false; } 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(); if (!wmutex && !(wmutex = getMutexHandle(-1, true))) return false; if (!waitMutex(wmutex, block)) return false; if (mode == ReadLock) { int idx = 0; for (; idx < MAX_READERS; idx++) { rmutex = getMutexHandle(idx, false); if (!rmutex || waitMutex(rmutex, false)) break; CloseHandle(rmutex); } bool ok = true; if (idx >= MAX_READERS) { qWarning("QtLockedFile::lock(): too many readers"); rmutex = 0; ok = false; } else if (!rmutex) { rmutex = getMutexHandle(idx, true); if (!rmutex || !waitMutex(rmutex, false)) ok = false; } if (!ok && rmutex) { CloseHandle(rmutex); rmutex = 0; } ReleaseMutex(wmutex); if (!ok) return false; } else { Q_ASSERT(rmutexes.isEmpty()); for (int i = 0; i < MAX_READERS; i++) { Qt::HANDLE mutex = getMutexHandle(i, false); if (mutex) rmutexes.append(mutex); } if (rmutexes.size()) { DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(), TRUE, block ? INFINITE : 0); if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) { if (res != WAIT_TIMEOUT) qErrnoWarning("QtLockedFile::lock(): WaitForMultipleObjects failed"); m_lock_mode = WriteLock; // trick unlock() to clean up - semiyucky unlock(); 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; if (m_lock_mode == ReadLock) { ReleaseMutex(rmutex); CloseHandle(rmutex); rmutex = 0; } else { foreach(Qt::HANDLE mutex, rmutexes) { ReleaseMutex(mutex); CloseHandle(mutex); } rmutexes.clear(); ReleaseMutex(wmutex); } m_lock_mode = QtLockedFile::NoLock; return true; } QtLockedFile::~QtLockedFile() { if (isOpen()) unlock(); if (wmutex) CloseHandle(wmutex); } ukui-bluetooth/ukui-bluetooth/qtsingleapplication/qtlockedfile_unix.cpp0000644000175000017500000000661414201160062025724 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** 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 "qtlockedfile.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(); } ukui-bluetooth/ukui-bluetooth/qtsingleapplication/qtsinglecoreapplication.pri0000644000175000017500000000050414201160062027136 0ustar fengfengINCLUDEPATH += $$PWD DEPENDPATH += $$PWD HEADERS += $$PWD/qtsinglecoreapplication.h $$PWD/qtlocalpeer.h SOURCES += $$PWD/qtsinglecoreapplication.cpp $$PWD/qtlocalpeer.cpp QT *= network win32:contains(TEMPLATE, lib):contains(CONFIG, shared) { DEFINES += QT_QTSINGLECOREAPPLICATION_EXPORT=__declspec(dllexport) } ukui-bluetooth/ukui-bluetooth/qtsingleapplication/qtsingleapplication.pri0000644000175000017500000000111014201160062026257 0ustar fengfenginclude(../common.pri) 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 += $$PWD/qtsingleapplication.cpp $$PWD/qtlocalpeer.cpp HEADERS += $$PWD/qtsingleapplication.h $$PWD/qtlocalpeer.h } win32 { contains(TEMPLATE, lib):contains(CONFIG, shared):DEFINES += QT_QTSINGLEAPPLICATION_EXPORT else:qtsingleapplication-uselib:DEFINES += QT_QTSINGLEAPPLICATION_IMPORT } ukui-bluetooth/ukui-bluetooth/qtsingleapplication/qtsingleapplication.h0000644000175000017500000000761714201160062025736 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** 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 *peer; QWidget *actWin; }; #endif // QTSINGLEAPPLICATION_H ukui-bluetooth/ukui-bluetooth/qtsingleapplication/qtlockedfile.h0000644000175000017500000000630714201160062024325 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** 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 ukui-bluetooth/ukui-bluetooth/qtsingleapplication/QtSingleApplication0000644000175000017500000000004114201160062025330 0ustar fengfeng#include "qtsingleapplication.h" ukui-bluetooth/ukui-bluetooth/qtsingleapplication/qtsingleapplication.cpp0000644000175000017500000002701014201160062026256 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** 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 "qtsingleapplication.h" #include "qtlocalpeer.h" #include /*! \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) { actWin = 0; peer = new QtLocalPeer(this, appId); connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); } /*! 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 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 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 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) { actWin = aw; if (activateOnMessage) connect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow())); else disconnect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow())); } /*! Returns the applications activation window if one has been set by calling setActivationWindow(), otherwise returns 0. \sa setActivationWindow() */ QWidget* QtSingleApplication::activationWindow() const { return actWin; } /*! 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 (actWin) { actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized); actWin->raise(); actWin->activateWindow(); } } /*! \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 */ ukui-bluetooth/ukui-bluetooth/qtsingleapplication/qtsinglecoreapplication.cpp0000644000175000017500000001235514201160062027135 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** 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 "qtsinglecoreapplication.h" #include "qtlocalpeer.h" /*! \class QtSingleCoreApplication qtsinglecoreapplication.h \brief A variant of the QtSingleApplication class for non-GUI applications. This class is a variant of QtSingleApplication suited for use in console (non-GUI) applications. It is an extension of QCoreApplication (instead of QApplication). It does not require the QtGui library. The API and usage is identical to QtSingleApplication, except that functions relating to the "activation window" are not present, for obvious reasons. Please refer to the QtSingleApplication documentation for explanation of the usage. A QtSingleCoreApplication instance can communicate to a QtSingleApplication instance if they share the same application id. Hence, this class can be used to create a light-weight command-line tool that sends commands to a GUI application. \sa QtSingleApplication */ /*! Creates a QtSingleCoreApplication object. The application identifier will be QCoreApplication::applicationFilePath(). \a argc and \a argv are passed on to the QCoreAppliation constructor. */ QtSingleCoreApplication::QtSingleCoreApplication(int &argc, char **argv) : QCoreApplication(argc, argv) { peer = new QtLocalPeer(this); connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); } /*! Creates a QtSingleCoreApplication object with the application identifier \a appId. \a argc and \a argv are passed on to the QCoreAppliation constructor. */ QtSingleCoreApplication::QtSingleCoreApplication(const QString &appId, int &argc, char **argv) : QCoreApplication(argc, argv) { peer = new QtLocalPeer(this, appId); connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); } /*! 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 QtSingleCoreApplication::isRunning() { return peer->isClient(); } /*! Tries to send the text \a message to the currently running instance. The QtSingleCoreApplication 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 QtSingleCoreApplication::sendMessage(const QString &message, int timeout) { return peer->sendMessage(message, timeout); } /*! Returns the application identifier. Two processes with the same identifier will be regarded as instances of the same application. */ QString QtSingleCoreApplication::id() const { return peer->applicationId(); } /*! \fn void QtSingleCoreApplication::messageReceived(const QString& message) This signal is emitted when the current instance receives a \a message from another instance of this application. \sa sendMessage() */ ukui-bluetooth/ukui-bluetooth/qtsingleapplication/QtLockedFile0000644000175000017500000000003214201160062023724 0ustar fengfeng#include "qtlockedfile.h" ukui-bluetooth/ukui-bluetooth/ukui-bluetooth.qrc0000644000175000017500000000023014201160062021110 0ustar fengfeng ../translations/ukui-bluetooth_zh_CN.qm ukui-bluetooth/ukui-bluetooth/ukui-bluetooth.pro0000644000175000017500000000522214201160062021131 0ustar fengfengTARGET = ukui-bluetooth DESTDIR = . TEMPLATE = app QT += core gui dbus KWindowSystem x11extras greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 link_pkgconfig PKGCONFIG += gsettings-qt gio-2.0 # 适配窗口管理器圆角阴影 LIBS +=-lpthread LIBS +=-lX11 -lXrandr -lXinerama -lXi -lXcursor LIBS += -L /usr/lib/x86_64-linux-gnu -l KF5BluezQt -lgio-2.0 -lglib-2.0 -lukui-log4qt QMAKE_LFLAGS += -D_FORTIFY_SOURCE=2 -O2 inst1.files += ../data/org.bluez.Agent1.conf inst1.path = /etc/dbus-1/system.d/ inst2.files += ../data/org.ukui.bluetooth.gschema.xml inst2.path = /usr/share/glib-2.0/schemas/ #inst3.files += data/ukui-bluetooth.desktop #inst3.files = /etc/xdg/autostart/ target.source += $$TARGET target.path = /usr/bin INSTALLS += inst1 \ inst2 \ # inst3 \ target exists(/usr/include/KF5/BluezQt/bluezqt/battery.h){DEFINES += BATTERY} # The following define makes your compiler emit warnings if you use # any Qt feature that has been marked 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 # QT_NO_WARNING_OUTPUT \ # QT_NO_DEBUG_OUTPUT # You can also make your code fail to compile if it uses 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 unix { UI_DIR = .ui MOC_DIR = .moc OBJECTS_DIR = .obj } SOURCES += \ component/switchaction.cpp \ component/switchbutton.cpp \ fileSend/bluetoothfiletransferwidget.cpp \ fileReceive/filereceivingpopupwidget.cpp \ main/main.cpp \ main/featureswidget.cpp \ pin/pincodewidget.cpp \ fileSend/deviceseleterwidget.cpp \ config/xatom-helper.cpp \ daemon/bluetoothdbus.cpp \ agent/bluetoothobexagent.cpp \ agent/bluetoothagent.cpp HEADERS += \ component/switchaction.h \ component/switchbutton.h \ fileSend/bluetoothfiletransferwidget.h \ main/featureswidget.h \ fileReceive/filereceivingpopupwidget.h \ pin/pincodewidget.h \ fileSend/deviceseleterwidget.h \ config/xatom-helper.h \ daemon/bluetoothdbus.h \ agent/bluetoothobexagent.h \ agent/bluetoothagent.h #TRANSLATIONS += \ # ../translations/ukui-bluetooth_zh_CN.ts # Default rules for deployment. #qnx: target.path = /tmp/$${TARGET}/bin #else: unix:!android: target.path = /opt/$${TARGET}/bin #!isEmpty(target.path): INSTALLS += target RESOURCES += \ ukui-bluetooth.qrc ukui-bluetooth/ukui-bluetooth/main/0000755000175000017500000000000014205120476016363 5ustar fengfengukui-bluetooth/ukui-bluetooth/main/featureswidget.h0000644000175000017500000001360314201620261021552 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2021 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 FEATURESWIDGET_H #define FEATURESWIDGET_H #include "../fileSend/bluetoothfiletransferwidget.h" #include "../agent/bluetoothagent.h" #include "daemon/bluetoothdbus.h" #include "../agent/bluetoothobexagent.h" #include "../component/switchaction.h" #include #include #include #include #include #include #include #include #include #ifdef BATTERY #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define LIST_PATH "/etc/pairDevice.list" #define RFKILL_DEV "/dev/rfkill" using namespace std; class BluetoothDbus; class FeaturesWidget : public QWidget { Q_OBJECT public: FeaturesWidget(QWidget *parent = nullptr); ~FeaturesWidget(); void showBluetoothTrayIcon(); void InitTrayMenu(); void setWidgetPosition(); void InitAgentAndDbus(); void M_registerAgent(); void Pair_device_by_address(QString); void Disconnect_device_by_address(QString); void Remove_device_by_address(QString); void Connect_device_by_address(QString); void Connect_device_audio(QString); void Send_files_by_address(QString); void Turn_on_or_off_bluetooth(bool); void Connect_device(BluezQt::DevicePtr); void Open_bluetooth_settings(); void SendNotifyMessage(QString); void NotifyOnOff(); void Dbus_file_transfer(QStringList); void Monitor_sleep_signal(); bool Connect_device_name_white_list(QString dev_name); void Connect_the_last_connected_device(); void adapterChangeFUN(); void writeDeviceInfoToFile(const QString& devAddress,const QString& devName, const BluezQt::Device::Type type); void removeDeviceInfoToFile(const QString& devAddress); void setTrayIcon(bool); QStringList getDeviceConnectTimeList(); bool exit_flag = false; signals: void ProgramExit(); public slots: void TraySignalProcessing(QAction *action); void file_transfer_session_add(BluezQt::ObexSessionPtr); void file_transfer_creator(QString); void close_session(); void propertyChanged(QString name, QVariantMap map, QStringList list); void GSettings_value_chanage(const QString &key); void Dbus_bluetooth_switch(bool); void Monitor_sleep_Slot(bool); void adapterPoweredChanged(bool value); void adapterDeviceRemove(BluezQt::DevicePtr ptr); void Remove_device_by_devicePtr(BluezQt::DevicePtr ptr); void Start_notify_timer(BluezQt::DevicePtr); void Stop_notify_timer(BluezQt::DevicePtr); void showWarnningMesgBox(); private: QList is_connected; QSystemTrayIcon *bluetooth_tray_icon = nullptr; QMenu *tray_Menu = nullptr; SwitchAction *m_action = nullptr; QGSettings *settings = nullptr; QStringList paired_device_address; QStringList paired_device; QString finally_connect_the_device; QString Default_Adapter; QString File_save_path; QString cur_adapter_address; QStringList adapter_list; QString selected_file; quint64 transfer_file_size = 0; bool flag = true; BluetoothDbus *session_dbus = nullptr; BluetoothFileTransferWidget *transfer_widget = nullptr; BluezQt::DevicePtr m_device; BluezQt::Manager *m_manager = nullptr; BluezQt::Adapter *m_adapter = nullptr; BluezQt::ObexManager *obex_manager = nullptr; BluetoothAgent *bluetoothAgent = nullptr; BluetoothObexAgent *bluetoothObexAgent = nullptr; BluezQt::ObexObjectPush *opp = nullptr; BluezQt::ObexTransferPtr filePtr = nullptr; QTimer *notify_timer; QDBusObjectPath pre_session; bool dev_remove_flag = false; bool sleep_flag = false; bool dev_connected_when_sleep = false; QString pair_device_file; int dev_callbak_flag = 0; bool pair_flag = true; QTimer * callBackConnectTimer; void initAllTimer(); } ; #endif // FEATURESWIDGET_H ukui-bluetooth/ukui-bluetooth/main/featureswidget.cpp0000644000175000017500000017475414205120476022133 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2021 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 "featureswidget.h" #include enum rfkill_type { RFKILL_TYPE_ALL = 0, RFKILL_TYPE_WLAN, RFKILL_TYPE_BLUETOOTH, RFKILL_TYPE_UWB, RFKILL_TYPE_WIMAX, RFKILL_TYPE_WWAN, }; enum rfkill_operation { RFKILL_OP_ADD = 0, RFKILL_OP_DEL, RFKILL_OP_CHANGE, RFKILL_OP_CHANGE_ALL, }; struct rfkill_event { uint32_t idx; uint8_t type; uint8_t op; uint8_t soft; uint8_t hard; }; enum { OPT_b = (1 << 0), /* must be = 1 */ OPT_u = (1 << 1), OPT_l = (1 << 2), }; static guint watch = 0; bool spe_bt_node = false; bool not_hci_node = false; bool M_adapter_flag = false; bool M_power_on = false; static gboolean rfkill_event(GIOChannel *chan, GIOCondition cond, gpointer data) { unsigned char buf[32]; struct rfkill_event *event = (struct rfkill_event *)buf; char sysname[PATH_MAX]; ssize_t len; int fd, id; if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) return FALSE; fd = g_io_channel_unix_get_fd(chan); memset(buf, 0, sizeof(buf)); len = read(fd, buf, sizeof(buf)); if (len < 0) { if (errno == EAGAIN) return TRUE; return FALSE; } if (len != sizeof(struct rfkill_event)) return TRUE; qDebug("RFKILL event idx %u type %u op %u soft %u hard %u", event->idx, event->type, event->op, event->soft, event->hard); if (event->type != RFKILL_TYPE_BLUETOOTH && event->type != RFKILL_TYPE_ALL) { qDebug() << Q_FUNC_INFO << "Not bt====" ; return TRUE; } memset(sysname, 0, sizeof(sysname)); snprintf(sysname, sizeof(sysname) - 1, "/sys/class/rfkill/rfkill%u/name", event->idx); fd = open(sysname, O_RDONLY); if (fd < 0) { qDebug () << Q_FUNC_INFO << __LINE__; return TRUE; } if (read(fd, sysname, sizeof(sysname) - 1) < 4) { close(fd); qDebug () << Q_FUNC_INFO << __LINE__; return TRUE; } close(fd); if (g_str_has_prefix(sysname, "tpacpi_bluetooth_sw") == TRUE) { spe_bt_node = true; qDebug () << Q_FUNC_INFO << "spe_bt_node" << spe_bt_node << __LINE__; if (event->soft) { not_hci_node = true ; qDebug () << Q_FUNC_INFO << "event->soft:" << event->soft << __LINE__; } else not_hci_node = false ; } else if (g_str_has_prefix(sysname, "hci") == TRUE) { qDebug () << Q_FUNC_INFO << "not_hci_node:FALSE" << __LINE__; not_hci_node = false; } else { qDebug () << Q_FUNC_INFO << "not_hci_node:TRUE" << __LINE__; not_hci_node = true; } return TRUE; } void rfkill_init(void) { qDebug () << Q_FUNC_INFO << __LINE__; int fd; GIOChannel *channel; fd = open("/dev/rfkill", O_RDWR); if (fd < 0) { return; } channel = g_io_channel_unix_new(fd); g_io_channel_set_close_on_unref(channel, TRUE); watch = g_io_add_watch(channel, GIOCondition(G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR), rfkill_event, NULL); g_io_channel_unref(channel); } void rfkill_set_idx(void) { qDebug () << Q_FUNC_INFO << __LINE__; struct rfkill_event event; int rf_fd; int mode; int rf_type; int rf_idx; unsigned rf_opt = 0; /* Must have one or two params */ mode = O_RDWR | O_NONBLOCK; rf_type = RFKILL_TYPE_BLUETOOTH; rf_idx = -1; rf_fd = open("/dev/rfkill", mode); memset(&event, 0, sizeof(event)); if (rf_type >= 0) { event.type = rf_type; event.op = RFKILL_OP_CHANGE_ALL; } if (rf_idx >= 0) { event.idx = rf_idx; event.op = RFKILL_OP_CHANGE; } /* Note: OPT_b == 1 */ event.soft = (rf_opt & OPT_b); write(rf_fd, &event, sizeof(event)); } void rfkill_exit(void) { if (watch == 0) return; g_source_remove(watch); watch = 0; } static qint64 getFileSize(QString filename) { QFileInfo info(filename); if (info.exists()) return info.size(); else return 0; } FeaturesWidget::FeaturesWidget(QWidget *parent) : QWidget(parent) { rfkill_init(); rfkill_set_idx(); //=============初始化蓝牙管理器,失败则退出进程=================== m_manager = new BluezQt::Manager(this); BluezQt::InitManagerJob *job = m_manager->init(); job->exec(); qDebug() << m_manager->isInitialized(); if(!m_manager->isInitialized()){ qDebug() << "BluezQt::Manager init failed !!!"; qDebug() << "Program exit !!!"; exit_flag = true; return; } if(!m_manager->isOperational()){ qDebug() << "BluezQt::Manager manager is not operational !!!"; qDebug() << "BlueZ system daemon is not running"; qDebug() << "Program exit !!!"; exit_flag = true; return; } //========================END================================= obex_manager = new BluezQt::ObexManager(this); BluezQt::InitObexManagerJob *obex_job = obex_manager->init(); obex_job->exec(); qDebug() << Q_FUNC_INFO << obex_manager->isInitialized() << obex_manager->isOperational() << obex_manager->sessions().size(); connect(obex_manager,&BluezQt::ObexManager::sessionAdded,this,&FeaturesWidget::file_transfer_session_add); InitAgentAndDbus(); M_registerAgent(); //==============获取gsettings的配置信息========================== if(QGSettings::isSchemaInstalled("org.ukui.bluetooth")){ settings = new QGSettings("org.ukui.bluetooth"); paired_device_address = settings->get("paired-device-address").toStringList(); finally_connect_the_device = settings->get("finally-connect-the-device").toString(); paired_device = settings->get("paired-device").toStringList(); Default_Adapter = settings->get("adapter-address").toString(); File_save_path = settings->get("file-save-path").toString(); qDebug() << "GSetting Value: " << Default_Adapter << finally_connect_the_device << paired_device; connect(settings, &QGSettings::changed,this,&FeaturesWidget::GSettings_value_chanage); } //========================END=================================== if(m_manager->adapters().size()){ adapter_list.clear(); for(int i = 0;i < m_manager->adapters().size(); i++){ adapter_list << m_manager->adapters().at(i).data()->address(); } settings->set("adapter-address-list",QVariant::fromValue(adapter_list)); qDebug() << Q_FUNC_INFO << adapter_list <<__LINE__; } if(m_manager->adapters().size() == 0){ qDebug() << "no bluetooth adapter !!!"; qDebug() << "Program exit !!!"; not_hci_node = true; M_adapter_flag = false; }else if(m_manager->adapters().size() == 1){ m_adapter = m_manager->adapters().at(0).data(); settings->set("adapter-address",QVariant::fromValue(m_adapter->address())); M_adapter_flag = true; }else{ if(adapter_list.indexOf(Default_Adapter) != -1){ m_adapter = m_manager->adapterForAddress(Default_Adapter).data(); }else{ m_adapter = m_manager->adapterForAddress(adapter_list.at(0)).data(); } M_adapter_flag = true; } initAllTimer(); showBluetoothTrayIcon(); adapterChangeFUN(); if (!not_hci_node) cur_adapter_address = m_adapter->address(); qDebug() << "===========" << m_manager->isBluetoothBlocked(); if (!not_hci_node) Turn_on_or_off_bluetooth(settings->get("switch").toBool()); if(File_save_path.isEmpty()){ settings->set("file-save-path",QVariant::fromValue(QDir::homePath())); } qDebug() << Q_FUNC_INFO << m_manager->isInitialized() << m_manager->isOperational(); if (!not_hci_node) NotifyOnOff(); if (!not_hci_node) Monitor_sleep_signal(); if(!not_hci_node && !m_manager->isBluetoothBlocked() && m_adapter->isPowered()){ QTimer::singleShot(500,this,[=]{ Connect_the_last_connected_device(); }); } qDebug() << Q_FUNC_INFO << "end" << __LINE__; } FeaturesWidget::~FeaturesWidget() { delete settings; rfkill_exit(); } void FeaturesWidget::initAllTimer() { notify_timer = new QTimer(); connect(notify_timer, &QTimer::timeout, this, [=]() { if (nullptr == m_device) { QString text = QString(tr("The connection with the Bluetooth device is successful!")); SendNotifyMessage(text); } else { if (m_device->isPaired() && m_device->isConnected()) { is_connected.push_back(m_device->name()); QString text = QString(tr("The connection with the Bluetooth device “%1” is successful!").arg(m_device->name())); SendNotifyMessage(text); } } }); callBackConnectTimer = new QTimer(); callBackConnectTimer->setInterval(1000);//2000 ms 最好 connect(callBackConnectTimer, &QTimer::timeout, this, [=]() { callBackConnectTimer->stop(); Connect_the_last_connected_device(); }); } void FeaturesWidget::showBluetoothTrayIcon() { qDebug () <setProperty("setIconHighlightEffectDefaultColor", tray_Menu->palette().color(QPalette::Active, QPalette::Base)); tray_Menu->setPalette(palette); tray_Menu->setMinimumWidth(240); connect(tray_Menu,&QMenu::triggered,this,&FeaturesWidget::TraySignalProcessing); //Create taskbar tray icon and connect to signal slot //创建任务栏托盘图标,并连接信号槽 bluetooth_tray_icon = new QSystemTrayIcon(this); bluetooth_tray_icon->setContextMenu(tray_Menu); bluetooth_tray_icon->setToolTip(tr("Bluetooth")); bluetooth_tray_icon->setVisible(settings->get("tray-show").toBool()); if (spe_bt_node) { setTrayIcon(not_hci_node); } else { if (m_manager->adapters().size()) { setTrayIcon((nullptr != m_adapter) && (m_adapter->isPowered())); } else { bluetooth_tray_icon->setVisible(false); } } connect(bluetooth_tray_icon, &QSystemTrayIcon::activated, [=](QSystemTrayIcon::ActivationReason reason){ switch (reason) { case QSystemTrayIcon::DoubleClick: /* 来自于双击激活。 */ case QSystemTrayIcon::Trigger: /* 来自于单击激活。 */ InitTrayMenu(); break; case QSystemTrayIcon::Context: //InitTrayMenu(); break; } }); } void FeaturesWidget::InitTrayMenu() { qDebug() << Q_FUNC_INFO << spe_bt_node << not_hci_node << M_adapter_flag; tray_Menu->clear(); bool btPower = false ; if (spe_bt_node) { if (not_hci_node) btPower = false; else { if (!M_adapter_flag) return; else btPower = m_adapter->isPowered(); } } else { if (not_hci_node) return; else { btPower = m_adapter->isPowered(); } } m_action = new SwitchAction(this); //m_action->setBtnStatus(m_adapter->isPowered()); m_action->setBtnStatus(btPower); connect(m_action,&SwitchAction::sendBtnStatus,this,[=](bool value){ Turn_on_or_off_bluetooth(value); }); QWidgetAction *switch_txt = new QWidgetAction(tray_Menu); switch_txt->setDefaultWidget(m_action); tray_Menu->addAction(switch_txt); tray_Menu->addSeparator(); qDebug() << Q_FUNC_INFO << flag << btPower;//m_adapter->isPowered(); //if(m_adapter->isPowered()){ if(btPower){ QList device_list = m_adapter->devices(); qDebug() << Q_FUNC_INFO << device_list.size(); QAction *head = new QAction(tr("My Devices")); head->setDisabled(true); tray_Menu->addAction(head); bool head_rm = true; for(int i=0; i < device_list.size(); i++){ if(device_list.at(i)->isPaired()){ QPalette palette; head_rm = false; palette.setBrush(QPalette::Base,QColor(Qt::black)); palette.setBrush(QPalette::Text,QColor(Qt::white)); QString devname = device_list.at(i)->name(); QFontMetrics fontMetrics(head->font()); devname = fontMetrics.elidedText(devname, Qt::ElideRight, 150); QAction *device_action = new QAction(devname,tray_Menu); device_action->setCheckable(true); QMenu *device_menu = new QMenu(); device_action->setToolTip(device_list.at(i)->name()); device_menu->setPalette(palette); device_action->setObjectName(device_list.at(i)->address()); QAction *status = new QAction(tray_Menu); QAction *send = new QAction(tray_Menu); QAction *remove = new QAction(tray_Menu); if(!flag){ device_action->setChecked(true); } status->setStatusTip(device_list.at(i)->address()); send->setStatusTip(device_list.at(i)->address()); remove->setStatusTip(device_list.at(i)->address()); if(device_list.at(i)->isConnected()){ device_action->setChecked(true); if (device_list.at(i)->type() == BluezQt::Device::Mouse || device_list.at(i)->type() == BluezQt::Device::Keyboard) { remove->setText(tr("Remove")); } else { status->setText(tr("Disconnection")); } #ifdef BATTERY BluezQt::BatteryPtr dev_battery = device_list.at(i)->battery(); qDebug() << Q_FUNC_INFO << __LINE__ << dev_battery.isNull(); if(!dev_battery.isNull()){ QAction *battery = new QAction(); battery->setDisabled(true); battery->setIcon(QIcon::fromTheme("battery-level-100-symbolic")); battery->setText(tr("Power ")+QString::number(dev_battery->percentage(),10)+"%"); device_menu->addAction(battery); } #endif }else{ device_action->setChecked(false); if(device_list.at(i)->type()==BluezQt::Device::Headset || device_list.at(i)->type()==BluezQt::Device::Headphones || device_list.at(i)->type()==BluezQt::Device::AudioVideo) status->setText(tr("Connect audio")); else status->setText(tr("Connection")); remove->setText(tr("Remove")); device_menu->addAction(remove); } if (device_list.at(i)->type() == BluezQt::Device::Mouse || device_list.at(i)->type() == BluezQt::Device::Keyboard) { device_menu->addAction(remove); } else { device_menu->addAction(status); } send->setText(tr("Send files")); if(device_list.at(i)->type()==BluezQt::Device::Phone || device_list.at(i)->type()==BluezQt::Device::Computer) { if (qgetenv("DESKTOP_SESSION") == "ukui") device_menu->addAction(send); } qDebug() << Q_FUNC_INFO << device_menu->size(); disconnect(device_list.at(i).data(), &BluezQt::Device::connectedChanged, device_action, nullptr); connect(device_list.at(i).data(),&BluezQt::Device::connectedChanged,device_action,[=](bool value){ qDebug() << Q_FUNC_INFO << value << __LINE__; if(value) { // device_menu->setIcon(QIcon::fromTheme("ukui-dialog-success")); device_action->setChecked(true); if (device_list.at(i)->type() == BluezQt::Device::Mouse || device_list.at(i)->type() == BluezQt::Device::Keyboard) { device_menu->removeAction(status); } else { status->setText(tr("Disconnection")); device_menu->addAction(status); device_menu->removeAction(remove); } #ifdef BATTERY BluezQt::BatteryPtr dev_battery = device_list.at(i)->battery(); if(!dev_battery.isNull()){ QAction *battery = new QAction(); battery->setDisabled(true); battery->setIcon(QIcon::fromTheme("battery-level-100-symbolic")); battery->setText(tr("Power ")+QString::number(dev_battery->percentage(),10)+"%"); device_menu->addAction(battery); } #endif send->setText(tr("Send files")); if(device_list.at(i)->type()==BluezQt::Device::Phone || device_list.at(i)->type()==BluezQt::Device::Computer) { if (qgetenv("DESKTOP_SESSION") == "ukui") device_menu->addAction(send); } } else { device_action->setChecked(false); if(device_list.at(i)->type()==BluezQt::Device::Headset || device_list.at(i)->type()==BluezQt::Device::Headphones || device_list.at(i)->type()==BluezQt::Device::AudioVideo) status->setText(tr("Connect audio")); else status->setText(tr("Connection")); remove->setText(tr("Remove")); device_menu->clear(); device_menu->addAction(remove); device_menu->addAction(status); send->setText(tr("Send files")); if(device_list.at(i)->type()==BluezQt::Device::Phone || device_list.at(i)->type()==BluezQt::Device::Computer) { if (qgetenv("DESKTOP_SESSION") == "ukui") device_menu->addAction(send); } if (device_list.at(i)->type() == BluezQt::Device::Mouse || device_list.at(i)->type() == BluezQt::Device::Keyboard){ device_menu->removeAction(status); } } }); tray_Menu->addAction(device_action); device_action->setMenu(device_menu); // connect(device_menu,&QMenu::triggered,this,&FeaturesWidget::TrayItemSignalProcessing); } } if (head_rm) { tray_Menu->removeAction(head); } } tray_Menu->addSeparator(); QAction *settins_action = new QAction(tr("Bluetooth settings"),tray_Menu); settins_action->setCheckable(true); tray_Menu->addAction(settins_action); if (!QFile("/usr/bin/ukui-panel").exists()) { tray_Menu->move(bluetooth_tray_icon->geometry().x()+16,bluetooth_tray_icon->geometry().y()-50); tray_Menu->exec(); } else { setWidgetPosition(); } } void FeaturesWidget::setWidgetPosition() { #define MARGIN 4 //menu->exec(); int width = tray_Menu->sizeHint().width(); int height= tray_Menu->sizeHint().height(); qDebug()<<"menu 's width height"< reply=iface.call("GetPrimaryScreenGeometry"); //reply获取的参数共5个,分别是 主屏可用区域的起点x坐标,主屏可用区域的起点y坐标,主屏可用区域的宽度,主屏可用区域高度,任务栏位置 // reply.value(); if (!iface.isValid() || !reply.isValid() || reply.value().size()<5) { qCritical() << QDBusConnection::sessionBus().lastError().message(); this->setGeometry(0,0,width,height); } // qDebug()<setGeometry(position_list.at(0).toInt()+position_list.at(2).toInt()-width-MARGIN, position_list.at(1).toInt()+MARGIN, width,height); break; //任务栏位于左边 case 2: tray_Menu->setGeometry(position_list.at(0).toInt()+MARGIN, position_list.at(1).toInt()+reply.value().at(3).toInt()-height-MARGIN, width,height); break; //任务栏位于右边 case 3: tray_Menu->setGeometry(position_list.at(0).toInt()+position_list.at(2).toInt()-width-MARGIN, position_list.at(1).toInt()+reply.value().at(3).toInt()-height-MARGIN, width,height); break; //任务栏位于下方 default: tray_Menu->setGeometry(position_list.at(0).toInt()+position_list.at(2).toInt()-width-MARGIN, position_list.at(1).toInt()+reply.value().at(3).toInt()-height-MARGIN, width,height); break; } tray_Menu->show(); } void FeaturesWidget::InitAgentAndDbus() { session_dbus = new BluetoothDbus(this); connect(session_dbus,&BluetoothDbus::ConnectTheSendingDevice,this,&FeaturesWidget::Pair_device_by_address); connect(session_dbus,&BluetoothDbus::DisconnectTheSendingDevice,this,&FeaturesWidget::Disconnect_device_by_address); connect(session_dbus,&BluetoothDbus::RemoveTheSendingDevice,this,&FeaturesWidget::Remove_device_by_address); connect(session_dbus,&BluetoothDbus::sendTransferMesg,this,&FeaturesWidget::Dbus_file_transfer); connect(session_dbus,&BluetoothDbus::switch_signals,this,&FeaturesWidget::Dbus_bluetooth_switch); bluetoothAgent = new BluetoothAgent(this); connect(bluetoothAgent, &BluetoothAgent::agentRemoveDevice, this, &FeaturesWidget::Remove_device_by_devicePtr); connect(bluetoothAgent, &BluetoothAgent::startNotifyTimer, this, &FeaturesWidget::Start_notify_timer); connect(bluetoothAgent, &BluetoothAgent::stopNotifyTimer, this, &FeaturesWidget::Stop_notify_timer); bluetoothObexAgent = new BluetoothObexAgent(this); } void FeaturesWidget::Start_notify_timer(BluezQt::DevicePtr) { notify_timer->setSingleShot(true); notify_timer->start(2000); } void FeaturesWidget::Stop_notify_timer(BluezQt::DevicePtr) { notify_timer->stop(); } void FeaturesWidget::showWarnningMesgBox() { QMessageBox *mbox = new QMessageBox(QMessageBox::Warning,tr("Warning"),tr("The selected file is empty, please select the file again !"),QMessageBox::Ok); QDesktopWidget *desktop = QApplication::desktop(); mbox->move((desktop->width()-mbox->width())/2,(desktop->height()-mbox->height())/2); mbox->exec(); } void FeaturesWidget::Pair_device_by_address(QString address) { qDebug() << Q_FUNC_INFO << address; BluezQt::DevicePtr device = m_adapter->deviceForAddress(address); if(device.isNull()) return; if(device->isPaired()){ if(device->type()==BluezQt::Device::Headset || device->type()==BluezQt::Device::Headphones || device->type()==BluezQt::Device::AudioVideo){ Connect_device_audio(address); }else{ Connect_device_by_address(address); } }else{ qDebug() << Q_FUNC_INFO << device->name(); BluezQt::PendingCall *call = device->pair(); connect(call,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *q){ qDebug() << Q_FUNC_INFO << __LINE__ <error() << q->errorText(); if(q->error() == 0){ //emit device.data()->pairedChanged(true); if(device->type()==BluezQt::Device::Headset || device->type()==BluezQt::Device::Headphones || device->type()==BluezQt::Device::AudioVideo){ Connect_device_audio(address); }else{ Connect_device_by_address(address); } } else { qDebug() << Q_FUNC_INFO << q->error(); emit device.data()->pairedChanged(false); } }); } } void FeaturesWidget::Disconnect_device_by_address(QString address) { qDebug() << Q_FUNC_INFO << address; BluezQt::DevicePtr device = m_adapter->deviceForAddress(address); if(device.isNull()) return; BluezQt::PendingCall *call = device->disconnectFromDevice(); connect(call,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *q){ if(q->error() == 0){ qDebug() << Q_FUNC_INFO; // QString text = QString(tr("Bluetooth device “%1” disconnected successfully").arg(device->name())); // SendNotifyMessage(text); }else{ qDebug() << Q_FUNC_INFO; // QString text = tr("Disconnect Error!!!"); // SendNotifyMessage(text); } }); } void FeaturesWidget::Remove_device_by_address(QString address) { BluezQt::DevicePtr device = m_adapter->deviceForAddress(address); Remove_device_by_devicePtr(device); } void FeaturesWidget::Connect_device_by_address(QString address) { qDebug() << Q_FUNC_INFO << (m_adapter == nullptr); BluezQt::DevicePtr device = m_adapter->deviceForAddress(address); if(device.isNull()){ qDebug() << Q_FUNC_INFO << "The connected device does not exist !"; return; } qDebug() << Q_FUNC_INFO << device->uuids(); BluezQt::DevicePtr finally_device = m_adapter->deviceForAddress(settings->get("finally-connect-the-device").toString()); if(finally_device.isNull() || address == settings->get("finally-connect-the-device").toString()){ qDebug() << Q_FUNC_INFO << finally_device.isNull() << address << settings->get("finally-connect-the-device").toString(); Connect_device(device); }else { if (device->type()==BluezQt::Device::Mouse) { Connect_device(device); } else { if(finally_device->isConnected()){ BluezQt::PendingCall *call = device->disconnectFromDevice(); connect(call,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *q){ if(q->error() == 0){ Connect_device(device); } }); } else { Connect_device(device); } } } } void FeaturesWidget::Connect_device_audio(QString address) { qDebug() << Q_FUNC_INFO << (m_adapter == nullptr); BluezQt::DevicePtr device = m_adapter->deviceForAddress(address); if(device.isNull()){ qDebug() << Q_FUNC_INFO << "The connected device does not exist !"; return; } qDebug() << Q_FUNC_INFO << device->uuids(); QList devlist = m_adapter->devices(); foreach (BluezQt::DevicePtr dev, devlist) { if (dev->address() == address) continue; if (dev->isConnected()) { if (dev->type()==BluezQt::Device::Headset || dev->type()==BluezQt::Device::Headphones || dev->type()==BluezQt::Device::AudioVideo) { BluezQt::PendingCall *call = dev->disconnectFromDevice(); connect(call,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *q){ if(q->error() == 0){ Connect_device(device); } }); return; } } } Connect_device(device); } void FeaturesWidget::Connect_device(BluezQt::DevicePtr device) { if (!device->isPaired()) { BluezQt::PendingCall *pair_call = device->pair(); connect(pair_call,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *pair_q){ if(pair_q->error() == 0) { qDebug() << Q_FUNC_INFO << "pair successful" << __LINE__; writeDeviceInfoToFile(device->address(),device->name(),device->type()); } else qDebug() << Q_FUNC_INFO << "pair failure" << __LINE__; device->setTrusted(true); BluezQt::PendingCall *conn_call = device->connectToDevice(); connect(conn_call,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *conn_q){ if(conn_q->error() == 0) { qDebug() << Q_FUNC_INFO << "connect successful" << __LINE__; settings->set("finally-connect-the-device",QVariant::fromValue(device->address())); writeDeviceInfoToFile(device->address(),device->name(),device->type()); } else { qDebug() << Q_FUNC_INFO << "connect failure" << conn_q->errorText() << __LINE__; } }); }); } else { BluezQt::PendingCall *call = device->connectToDevice(); qDebug() << Q_FUNC_INFO << device->adapter()->name(); device->setTrusted(true); qDebug() << Q_FUNC_INFO << call->error() << __LINE__; connect(call,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *q){ if(q->error() == 0){ qDebug() << Q_FUNC_INFO << __LINE__; QTimer::singleShot(500, [=]{ emit device->connectedChanged(true); }); // QString text = QString(tr("The connection with the Bluetooth device “%1” is successful!").arg(device->name())); // SendNotifyMessage(text); settings->set("finally-connect-the-device",QVariant::fromValue(device->address())); writeDeviceInfoToFile(device->address(),device->name(),device->type()); }else{ qDebug() << Q_FUNC_INFO << q->errorText(); // QString text = QString(tr("The connection with the Bluetooth device “%1” is failed!").arg(device->name())); // SendNotifyMessage(text); } }); } } void FeaturesWidget::Open_bluetooth_settings() { QProcess *process = new QProcess(this); QString cmd = "ukui-control-center"; QStringList arg; qDebug() << Q_FUNC_INFO; arg << "--bluetooth"; process->start(cmd,arg); } void FeaturesWidget::SendNotifyMessage(QString message) { QDBusInterface iface("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", QDBusConnection::sessionBus()); QList args; args< device_list = m_adapter->devices(); qDebug() << Q_FUNC_INFO << device_list.size(); for(int i=0; i < device_list.size(); i++){ if(device_list.at(i)->isPaired()){ connect(device_list.at(i).data(),&BluezQt::Device::connectedChanged,this,[=](bool value){ qDebug() << Q_FUNC_INFO << "connectedChanged"; if(value) { m_device = device_list.at(i); notify_timer->setSingleShot(true); notify_timer->start(2000); } else { if (!is_connected.contains(device_list.at(i)->name())) return; QString text = QString(tr("Bluetooth device “%1” disconnected!").arg(device_list.at(i)->name())); SendNotifyMessage(text); is_connected.removeOne(device_list.at(i)->name()); } }); } } connect(m_adapter, &BluezQt::Adapter::deviceAdded, this, [=](BluezQt::DevicePtr dev) { qDebug() << Q_FUNC_INFO << dev.data()->name(); connect(dev.data(),&BluezQt::Device::pairedChanged,this,[=](bool value){ qDebug() << Q_FUNC_INFO << "pairedChanged" << value; if(value && pair_flag) { pair_flag = false; QTimer::singleShot(500,this,[=]{ pair_flag = true; }); m_device = dev; notify_timer->setSingleShot(true); notify_timer->start(2000); } }); connect(dev.data(),&BluezQt::Device::connectedChanged,this,[=](bool value){ qDebug() << Q_FUNC_INFO << "connectedChanged" << value; if (dev.data()->isPaired()) { if(value) { m_device = dev; notify_timer->setSingleShot(true); notify_timer->start(2000); } else { if (!is_connected.contains(dev->name())) return; QString text = QString(tr("Bluetooth device “%1” disconnected!").arg(dev->name())); SendNotifyMessage(text); is_connected.removeOne(dev->name()); } } }); }); } void FeaturesWidget::Send_files_by_address(QString address) { selected_file = nullptr; if(!obex_manager->isOperational()){ BluezQt::PendingCall *call = obex_manager->startService(); connect(call,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *q){ QTimer::singleShot(1000,this,[=]{ obex_manager->registerAgent(bluetoothObexAgent)->errorText(); }); }); } QFileDialog fd; QList list = fd.sidebarUrls(); int sidebarNum = 8;//最大添加U盘数,可以自己定义 QString home = QDir::homePath().section("/", -1, -1); QString mnt = "/media/" + home + "/"; QDir mntDir(mnt); mntDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot); QFileInfoList filist = mntDir.entryInfoList(); QList mntUrlList; for (int i = 0; i < sidebarNum && i < filist.size(); ++i) { QFileInfo fi = filist.at(i); //华为990、9a0需要屏蔽最小系统挂载的目录 if (fi.fileName() == "2691-6AB8") continue; mntUrlList << QUrl("file://" + fi.filePath()); } QFileSystemWatcher fsw(&fd); fsw.addPath("/media/" + home + "/"); connect(&fsw, &QFileSystemWatcher::directoryChanged, &fd, [=, &sidebarNum, &mntUrlList, &list, &fd](const QString path) { QDir wmntDir(path); wmntDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot); QFileInfoList wfilist = wmntDir.entryInfoList(); mntUrlList.clear(); for (int i = 0; i < sidebarNum && i < wfilist.size(); ++i) { QFileInfo fi = wfilist.at(i); //华为990、9a0需要屏蔽最小系统挂载的目录 if (fi.fileName() == "2691-6AB8") continue; mntUrlList << QUrl("file://" + fi.filePath()); } fd.setSidebarUrls(list + mntUrlList); fd.update(); }); connect(&fd, &QFileDialog::finished, &fd, [=, &list, &fd]() { fd.setSidebarUrls(list); }); //自己QFileDialog的用法,这里只是列子 fd.setNameFilter(QLatin1String("All Files (*)")); fd.setDirectory(QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).at(0)); //这行要添加,设置左侧导航 fd.setSidebarUrls(list + mntUrlList); if (fd.exec() == QDialog::Accepted) { qDebug()<show(); } else { qDebug() << Q_FUNC_INFO << transfer_widget->get_send_data_state() << __LINE__; if (BluetoothFileTransferWidget::_SEND_FAILURE == transfer_widget->get_send_data_state() || BluetoothFileTransferWidget::_SEND_COMPLETE == transfer_widget->get_send_data_state() ) { emit transfer_widget->close_the_pre_session(); transfer_widget->close(); delete transfer_widget; transfer_widget = new BluetoothFileTransferWidget(selected_file,address); connect(transfer_widget,&BluetoothFileTransferWidget::sender_dev_name,this,&FeaturesWidget::file_transfer_creator); connect(transfer_widget,&BluetoothFileTransferWidget::close_the_pre_session,this,&FeaturesWidget::close_session); transfer_widget->show(); } // QMessageBox::warning(NULL, tr("bluetooth"), tr("A transfer is in progress..."), // QMessageBox::Ok,QMessageBox::Ok); } } } void FeaturesWidget::Turn_on_or_off_bluetooth(bool f) { qDebug() << Q_FUNC_INFO << f; if(f) { if (spe_bt_node) { M_power_on = true; if (not_hci_node) { rfkill_set_idx(); } } qDebug() << Q_FUNC_INFO << "spe_bt_node:" << spe_bt_node << " not_hci_node" << not_hci_node; if (!not_hci_node) { if (m_manager->isBluetoothBlocked()) m_manager->setBluetoothBlocked(false); BluezQt::PendingCall *call = m_adapter->setPowered(true); connect(call,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *p){ if(p->error() == 0){ flag = true; qDebug() << Q_FUNC_INFO<< "Set turn on Bluetooth: " << m_adapter->isPowered(); }else qDebug() << "Failed to turn on Bluetooth:" << p->errorText(); }); } }else{ if (spe_bt_node) { M_power_on = false; } BluezQt::PendingCall *call = m_adapter->setPowered(false); connect(call,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *p){ if(p->error() == 0){ flag = false; qDebug() << Q_FUNC_INFO <<"Set turn off Bluetooth: " << m_adapter->isPowered(); m_manager->setBluetoothBlocked(true); }else qDebug() << "Failed to turn off Bluetooth:" << p->errorText(); }); } } void FeaturesWidget::Dbus_file_transfer(QStringList file_path) { if(!obex_manager->isOperational()){ BluezQt::PendingCall *call = obex_manager->startService(); connect(call,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *q){ QTimer::singleShot(1000,this,[=]{ obex_manager->registerAgent(bluetoothObexAgent)->errorText(); }); }); } qDebug() << "Select file:" << file_path; selected_file = QUrl(file_path.first()).path(); if(!selected_file.isNull()){ if (getFileSize(selected_file) == 0) { showWarnningMesgBox(); return; } if (BluetoothFileTransferWidget::isShow == false) { transfer_widget = new BluetoothFileTransferWidget(selected_file,""); connect(transfer_widget,&BluetoothFileTransferWidget::sender_dev_name,this,&FeaturesWidget::file_transfer_creator); connect(transfer_widget,&BluetoothFileTransferWidget::close_the_pre_session,this,&FeaturesWidget::close_session); transfer_widget->show(); } else { if (BluetoothFileTransferWidget::_SEND_FAILURE == transfer_widget->get_send_data_state() || BluetoothFileTransferWidget::_SEND_COMPLETE == transfer_widget->get_send_data_state() ) { emit transfer_widget->close_the_pre_session(); transfer_widget->close(); delete transfer_widget; transfer_widget = new BluetoothFileTransferWidget(selected_file,""); connect(transfer_widget,&BluetoothFileTransferWidget::sender_dev_name,this,&FeaturesWidget::file_transfer_creator); connect(transfer_widget,&BluetoothFileTransferWidget::close_the_pre_session,this,&FeaturesWidget::close_session); transfer_widget->show(); } // QMessageBox::warning(NULL, tr("bluetooth"), tr("A transfer is in progress..."), // QMessageBox::Ok,QMessageBox::Ok); } } } void FeaturesWidget::Monitor_sleep_signal() { if (QDBusConnection::systemBus().connect("org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", "PrepareForSleep", this, SLOT(Monitor_sleep_Slot(bool)))) { qDebug() << "PrepareForSleep signal connected successfully to slot"; } else { qDebug() << "PrepareForSleep signal connection was not successful"; } } void FeaturesWidget::M_registerAgent() { qDebug() << m_manager->registerAgent(bluetoothAgent)->errorText(); if(!obex_manager->isOperational()){ BluezQt::PendingCall *call = obex_manager->startService(); connect(call,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *q){ QTimer::singleShot(1000,this,[=]{ obex_manager->registerAgent(bluetoothObexAgent)->errorText(); }); }); }else{ obex_manager->registerAgent(bluetoothObexAgent); } } bool FeaturesWidget::Connect_device_name_white_list(QString dev_name) { qDebug() << Q_FUNC_INFO << __LINE__; if (("Mi Air 2S" == dev_name) ) return true; return false; } void FeaturesWidget::Connect_the_last_connected_device() { qDebug() << Q_FUNC_INFO << "Connect Back to start"; QList devlist = m_adapter->devices(); foreach (BluezQt::DevicePtr devptr, devlist) { BluezQt::Device* dev = devptr.data(); if (dev->isPaired() && !dev->isConnected() && (dev->type() == BluezQt::Device::Keyboard || dev->type() == BluezQt::Device::Mouse)) { connect(dev, &BluezQt::Device::rssiChanged, this, [=] (qint16 value) { qDebug() << Q_FUNC_INFO << "rssiChanged" << dev->name() << value; BluezQt::PendingCall *pp = dev->connectToDevice(); connect(pp,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *call){ if(call->error() == 0) { emit dev->connectedChanged(true); writeDeviceInfoToFile(dev->address(),dev->name(),dev->type()); } else { qDebug() << Q_FUNC_INFO << "rssiChanged" << dev->name() << call->errorText(); } }); disconnect(dev, &BluezQt::Device::rssiChanged, nullptr, nullptr); }); } } QStringList target_list = getDeviceConnectTimeList(); qDebug() << Q_FUNC_INFO << "getDeviceConnectTimeList" << target_list.size(); foreach (QString dev_address, target_list) { BluezQt::Device* dev = m_adapter->deviceForAddress(dev_address).data(); if (dev != nullptr) { qDebug() << Q_FUNC_INFO << dev->type() << dev->name(); if (dev->isPaired() && !dev->isConnected() && (dev->type() == BluezQt::Device::Headset || dev->type() == BluezQt::Device::Headphones || dev->type() == BluezQt::Device::AudioVideo || Connect_device_name_white_list(dev->name()))) { qDebug() << Q_FUNC_INFO << dev->type() << dev->name(); BluezQt::PendingCall *pp = dev->connectToDevice(); connect(pp,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *call){ if(call->error() == 0){ writeDeviceInfoToFile(dev->address(),dev->name(),dev->type()); QTimer::singleShot(500, [=]{ emit dev->connectedChanged(true); }); }else{ qDebug() << Q_FUNC_INFO << "AudioVideo" << dev->name() << call->errorText(); } }); break; } } } QTimer::singleShot(10000, [=] { foreach (BluezQt::DevicePtr devptr, devlist) { BluezQt::Device* dev = devptr.data(); if (dev->isPaired() && !dev->isConnected() && (dev->type() == BluezQt::Device::Keyboard || dev->type() == BluezQt::Device::Mouse)) { disconnect(dev, &BluezQt::Device::rssiChanged, nullptr, nullptr); } } qDebug() << Q_FUNC_INFO << "rssiChanged Connecting Back to the end"; }); qDebug() << Q_FUNC_INFO << "Connecting Back to the end"; } // ===================蓝牙管理器设备操作监听======(主要针对系统的休眠和增加新的蓝牙硬件)======================= void FeaturesWidget::adapterChangeFUN() { qDebug() << Q_FUNC_INFO << __LINE__; if (!not_hci_node) { connect(m_adapter,&BluezQt::Adapter::poweredChanged,this,&FeaturesWidget::adapterPoweredChanged); connect(m_adapter,&BluezQt::Adapter::deviceRemoved,this,&FeaturesWidget::adapterDeviceRemove); } connect(m_manager,&BluezQt::Manager::adapterRemoved,this,[=](BluezQt::AdapterPtr adapter){ qDebug() << Q_FUNC_INFO << adapter->address() << adapter->name() <<__LINE__; // if(adapter_list.size() == 1) // { // QMessageBox::warning(NULL,tr("bluetooth"),tr("Bluetooth Adapter Abnormal!!!"),QMessageBox::Yes,QMessageBox::Yes); // } adapter_list.removeAll(adapter->address()); settings->set("adapter-address-list",QVariant::fromValue(adapter_list)); if(adapter_list.size() == 0){ not_hci_node = true; M_adapter_flag = false; qDebug() << Q_FUNC_INFO << spe_bt_node << not_hci_node << __LINE__; if (!spe_bt_node && not_hci_node) { //非休眠状态下提示蓝牙适配器 if (!sleep_flag) { QString text = QString(tr("no bluetooth adapter!")); SendNotifyMessage(text); } if(bluetooth_tray_icon->isVisible()) { bluetooth_tray_icon->setVisible(false); } } }else{ QTimer::singleShot(200,this,[=]{ if(!sleep_flag){ m_adapter = m_manager->adapterForAddress(adapter_list.at(0)).data(); // if(!m_adapter->isDiscoverable()){ // m_adapter->setDiscoverable(true); // m_adapter->setDiscoverableTimeout(0); // } connect(m_adapter,&BluezQt::Adapter::poweredChanged,this,&FeaturesWidget::adapterPoweredChanged); } }); } }); connect(m_manager,&BluezQt::Manager::adapterAdded,this,[=](BluezQt::AdapterPtr adapter){ qDebug() << Q_FUNC_INFO << adapter->address() << adapter->name() << bluetooth_tray_icon->isVisible() << adapter.data()->isPowered() <<__LINE__; adapter_list.append(adapter->address()); not_hci_node = false; if (!bluetooth_tray_icon->isVisible()) bluetooth_tray_icon->setVisible(true); settings->set("adapter-address-list",QVariant::fromValue(adapter_list)); m_adapter = adapter.data(); connect(m_adapter,&BluezQt::Adapter::poweredChanged,this,&FeaturesWidget::adapterPoweredChanged); M_adapter_flag = true ; if (spe_bt_node && M_power_on) { Turn_on_or_off_bluetooth(true); } NotifyOnOff(); }); connect(m_manager,&BluezQt::Manager::adapterChanged,this,[=](BluezQt::AdapterPtr adapter){ qDebug() << Q_FUNC_INFO << "adapterChanged" <<__LINE__; if (m_adapter->address() != adapter.data()->address()) { m_adapter = adapter.data(); connect(m_adapter,&BluezQt::Adapter::poweredChanged,this,&FeaturesWidget::adapterPoweredChanged); } }); connect(m_manager,&BluezQt::Manager::usableAdapterChanged,this,[=](BluezQt::AdapterPtr adapter){ qDebug() << Q_FUNC_INFO << "usableAdapterChanged" <<__LINE__; }); connect(m_manager,&BluezQt::Manager::operationalChanged,this,[=](bool status){ qDebug() << Q_FUNC_INFO << "operationalChanged " << status << __LINE__; setTrayIcon(status); if (status) { NotifyOnOff(); M_registerAgent(); } }); } // ===========================================END======================================================== void FeaturesWidget::writeDeviceInfoToFile(const QString &devAddress, const QString &devName, const BluezQt::Device::Type type) { QDBusMessage m = QDBusMessage::createMethodCall("com.bluetooth.systemdbus", "/", "com.bluetooth.interface", "writeKeyFile"); m << devAddress << devName << type; QDBusMessage response = QDBusConnection::systemBus().call(m); qDebug() << Q_FUNC_INFO << devAddress << devName << type << response.errorMessage(); } void FeaturesWidget::removeDeviceInfoToFile(const QString &devAddress) { QDBusMessage m = QDBusMessage::createMethodCall("com.bluetooth.systemdbus", "/", "com.bluetooth.interface", "removeKeyFile"); m << devAddress; QDBusMessage response = QDBusConnection::systemBus().call(m); qDebug() << Q_FUNC_INFO << devAddress << response.errorMessage(); } void FeaturesWidget::setTrayIcon(bool v) { if (v) { bluetooth_tray_icon->setIcon(QIcon::fromTheme("bluetooth-active-symbolic")); } else { if(QIcon::hasThemeIcon("bluetooth-error")) bluetooth_tray_icon->setIcon(QIcon::fromTheme("bluetooth-error")); else bluetooth_tray_icon->setIcon(QIcon::fromTheme("bluetooth-active-symbolic")); } } QStringList FeaturesWidget::getDeviceConnectTimeList() { QStringList pair_device_list; pair_device_list.clear(); if(!QFile::exists(LIST_PATH)) return pair_device_list; QVector pair_device_time_list; pair_device_time_list.clear(); GKeyFile *key_file = nullptr; key_file = g_key_file_new(); g_key_file_load_from_file(key_file,QString(LIST_PATH).toStdString().c_str(),G_KEY_FILE_NONE,NULL); gchar **list; bool ok; list = g_key_file_get_groups(key_file,NULL); for(int i = 0; list[i] != NULL; i++){ pair_device_list.append(QString::fromUtf8(list[i])); pair_device_time_list.append(QString::fromUtf8(g_key_file_get_string(key_file,list[i],"ConnectTime",NULL)).toInt(&ok,10)); } //*****************给从配置文件中得到的设备列表和设备对应的最后连接时间列表排序***********START************** for(int i = 0; i < pair_device_time_list.length(); i++){ for(int j = 0; j < pair_device_time_list.length()-i-1; j++){ if(pair_device_time_list.at(j) < pair_device_time_list.at(j+1)){ int max = pair_device_time_list.at(j); pair_device_time_list.replace(j,pair_device_time_list.at(j+1)); pair_device_time_list.replace(j+1,max); QString target = pair_device_list.at(j); pair_device_list.removeAt(j); pair_device_list.insert(j+1,target); } } } //************************************ END ****************************************************** g_key_file_free(key_file); return pair_device_list; } void FeaturesWidget::Monitor_sleep_Slot(bool sleep) { qDebug () << __FUNCTION__ << "app is sleep: " << sleep << __LINE__; if(!sleep){ qDebug() << "System wakes up from sleep !!!" << dev_remove_flag; sleep_flag = false; QTimer::singleShot(200,this,[=]{ if(m_manager->adapters().size()){ adapter_list.clear(); for(int i = 0;i < m_manager->adapters().size(); i++){ adapter_list << m_manager->adapters().at(i).data()->address(); } settings->set("adapter-address-list",QVariant::fromValue(adapter_list)); } if(m_manager->adapters().size()){ if(adapter_list.indexOf(cur_adapter_address) != -1){ m_adapter = m_manager->adapterForAddress(cur_adapter_address).data(); }else{ m_adapter = m_manager->adapterForAddress(adapter_list.at(0)).data(); } // if(!m_adapter->isDiscoverable()){ // m_adapter->setDiscoverable(true); // m_adapter->setDiscoverableTimeout(0); // } }else{ } if (m_manager->adapters().size()) { connect(m_adapter,&BluezQt::Adapter::poweredChanged,this,&FeaturesWidget::adapterPoweredChanged); dev_callbak_flag = 0; callBackConnectTimer->start(1000); //Connect_the_last_connected_device(); } }); }else{ sleep_flag = true; qDebug() << "System goes to sleep !!!" << dev_remove_flag; } qDebug() << Q_FUNC_INFO << "end"; } void FeaturesWidget::adapterPoweredChanged(bool value) { qDebug() << Q_FUNC_INFO << value; settings->set("switch",QVariant::fromValue(value)); flag = value; setTrayIcon(value); if (value == true) {//开启 callBackConnectTimer->start(1000); //Connect_the_last_connected_device(); } qDebug() << Q_FUNC_INFO << "end"; } void FeaturesWidget::Remove_device_by_devicePtr(BluezQt::DevicePtr ptr) { qDebug() << Q_FUNC_INFO; BluezQt::PendingCall *call = m_adapter->removeDevice(ptr); connect(call, &BluezQt::PendingCall::finished, this, [=](BluezQt::PendingCall *q) { if (q->error() == 0) removeDeviceInfoToFile(ptr.data()->address()); else qDebug() << Q_FUNC_INFO << "Agent Device Remove Failed!!!"; }); qDebug() << Q_FUNC_INFO << "end"; } void FeaturesWidget::adapterDeviceRemove(BluezQt::DevicePtr ptr) { qDebug() << Q_FUNC_INFO << ptr.data()->address() << ptr.data()->name(); removeDeviceInfoToFile(ptr.data()->address()); qDebug() << Q_FUNC_INFO << "end"; } void FeaturesWidget::TraySignalProcessing(QAction *action) { qDebug() << Q_FUNC_INFO << action->text() ; if(action->text() == tr("Bluetooth settings")){ Open_bluetooth_settings(); }else if(action->text() == tr("Disconnection")){ Disconnect_device_by_address(action->statusTip()); }else if(action->text() == tr("Connection")){ Connect_device_by_address(action->statusTip()); }else if(action->text() == tr("Connect audio")){ Connect_device_audio(action->statusTip()); }else if(action->text() == tr("Send files")){ Send_files_by_address(action->statusTip()); }else if(action->text() == tr("Remove")){ Remove_device_by_address(action->statusTip()); } } void FeaturesWidget::file_transfer_session_add(BluezQt::ObexSessionPtr sessionPtr) { qDebug() << Q_FUNC_INFO << sessionPtr->destination() << obex_manager->sessions().size(); qDebug() << Q_FUNC_INFO << sessionPtr->source() << m_adapter->address(); if(sessionPtr->source() == m_adapter->address()){ } } void FeaturesWidget::file_transfer_creator(QString dev) { // BluezQt::DevicePtr device = m_adapter->deviceForAddress(dev); // if(!device->isConnected()){ // Connect_device_by_address(dev); // } qDebug() << Q_FUNC_INFO << dev << m_adapter->address(); QMap map; map["Source"] = m_adapter->address(); map["Target"] = "OPP"; BluezQt::PendingCall *target = obex_manager->createSession(dev,map); qDebug() << Q_FUNC_INFO << target->error() << target->errorText(); connect(target,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *call){ QVariant v = call->value(); QDBusObjectPath session = v.value(); pre_session = session; opp = new BluezQt::ObexObjectPush(session); BluezQt::PendingCall *transfer = opp->sendFile(selected_file); qDebug() << Q_FUNC_INFO << transfer->error() << transfer->errorText(); connect(transfer,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *call){ qDebug() << Q_FUNC_INFO << __LINE__; QVariant v = call->value(); filePtr = v.value(); if(filePtr){ transfer_file_size = filePtr->size(); qDebug() << Q_FUNC_INFO << "Sending file size:" << transfer_file_size << __LINE__; // connect(ptr.get(),&BluezQt::ObexTransfer::transferredChanged,this,[=](quint64 vl){ // qDebug() << Q_FUNC_INFO << vl << __LINE__; // }); // connect(ptr.get(),&BluezQt::ObexTransfer::statusChanged,this,[=](BluezQt::ObexTransfer::Status status){ // qDebug() << Q_FUNC_INFO << status <<__LINE__; // }); if (QDBusConnection::sessionBus().connect("org.bluez.obex", filePtr->objectPath().path(), "org.freedesktop.DBus.Properties", "PropertiesChanged", this, SLOT(propertyChanged(QString, QVariantMap, QStringList)))) { qDebug() << "PropertiesChanged signal connected successfully to slot"; } else { qDebug() << "PropertiesChanged signal connection was not successful"; } }else{ transfer_widget->tranfer_error(); } }); }); qDebug() << Q_FUNC_INFO << obex_manager->sessions().size() << __LINE__; } void FeaturesWidget::close_session() { if(pre_session.path() != ""){ if (nullptr != filePtr) { qDebug() << Q_FUNC_INFO << "filePtr" <<__LINE__; BluezQt::PendingCall * stopFileSend = filePtr->cancel(); connect(stopFileSend,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *q){ qDebug() << Q_FUNC_INFO << q->errorText() << __LINE__; obex_manager->removeSession(pre_session); }); } } } void FeaturesWidget::propertyChanged(QString name, QVariantMap map, QStringList list) { // qDebug() << QString("properties of interface %1 changed").arg(name); for (QVariantMap::const_iterator it = map.cbegin(), end = map.cend(); it != end; ++it) { qDebug() << "property: " << it.key() << " value: " << it.value(); if(it.key() == "Transferred"){ QVariant value = it.value(); transfer_widget->set_m_progressbar_value(value.value()); }else if(it.key() == "Status"){ QVariant value = it.value(); if(value.value() == "active"){ transfer_widget->init_m_progressbar_value(transfer_file_size); }else if(value.value() == "error"){ qDebug() << Q_FUNC_INFO << __LINE__; filePtr->cancel(); } transfer_widget->get_transfer_status(value.value()); } } for (const auto& element : list) { qDebug() << "list element: " << element; } } void FeaturesWidget::GSettings_value_chanage(const QString &key) { qDebug() << Q_FUNC_INFO << key; if(key == "trayShow"){ if(bluetooth_tray_icon->isVisible() != settings->get(key).toBool()){ bluetooth_tray_icon->setVisible(settings->get(key).toBool()); } }else if(key == "file-save-path"){ }else if(key == "adapterAddress"){ m_adapter = m_manager->adapterForAddress(settings->get("adapterAddress").toString()).data(); cur_adapter_address = m_adapter->address(); connect(m_adapter,&BluezQt::Adapter::poweredChanged,this,&FeaturesWidget::adapterPoweredChanged); // if(!m_adapter->isDiscoverable()){ // m_adapter->setDiscoverable(true); // m_adapter->setDiscoverableTimeout(0); // } if(m_adapter->isPowered()) flag = true; else flag = false; } } //org.ukui.bluetooth dbus蓝牙开关接口 void FeaturesWidget::Dbus_bluetooth_switch(bool value) { qDebug() << Q_FUNC_INFO << value << settings->get("switch").toBool(); if(value != settings->get("switch").toBool()){ Turn_on_or_off_bluetooth(value); } } ukui-bluetooth/ukui-bluetooth/main/main.cpp0000644000175000017500000000427014201620261020007 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2021 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 "featureswidget.h" #include "../daemon/bluetoothdbus.h" #include #include #include #include #include #include #include #include int main(int argc, char *argv[]) { initUkuiLog4qt("ukui-bluetooth"); QApplication app(argc, argv); // QApplication::setStyle(QStyleFactory::create("ukui-default")); QApplication::setQuitOnLastWindowClosed(false); QString locale = QLocale::system().name(); // QString locale = "es"; QTranslator translator; if(locale == "zh_CN" || locale == "es" || locale == "fr" || locale == "de" || locale == "ru") {//中文 西班牙语 法语 德语 俄语 if(!translator.load("ukui-bluetooth_" + locale + ".qm", ":/translations/")) qDebug() << "Load translation file:"<< "ukui-bluetooth_" + locale + ".qm" << " failed!"; else app.installTranslator(&translator); } //加载Qt对话框默认的国际化 QTranslator qtTranslator; qtTranslator.load("qt_" + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath)); app.installTranslator(&qtTranslator); FeaturesWidget *w = new FeaturesWidget(); if( w->exit_flag ){ return 0; } return app.exec(); } ukui-bluetooth/ukui-bluetooth/agent/0000755000175000017500000000000014201622531016530 5ustar fengfengukui-bluetooth/ukui-bluetooth/agent/bluetoothobexagent.cpp0000644000175000017500000001054114201620261023135 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2021 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 "bluetoothobexagent.h" BluetoothObexAgent::BluetoothObexAgent(QObject *parent):ObexAgent(parent) { if(daemonIsNotRunning()){ qDebug() << Q_FUNC_INFO << __LINE__; QDBusConnection bus = QDBusConnection::sessionBus(); if (!bus.registerService("org.ukui.bluetooth")) { //注意命名规则-和_ qDebug() << bus.lastError().message(); exit(1); } // "QDBusConnection::ExportAllSlots"表示把类Hotel的所有Slot都导出为这个Object的method //qDebug() << Q_FUNC_INFO << bus.registerObject("/", "org.bluez.obex.Agent1", this, QDBusConnection::ExportAllContents); } } void BluetoothObexAgent::authorizePush(BluezQt::ObexTransferPtr transfer, BluezQt::ObexSessionPtr session, const BluezQt::Request &request) { // qDebug() << Q_FUNC_INFO << transfer->status() << transfer->fileName() << transfer->name() <objectPath().path() << transfer->transferred(); if(transfer->status() == BluezQt::ObexTransfer::Queued ){//|| transfer->status() == BluezQt::ObexTransfer::Complete receiving_widget = new FileReceivingPopupWidget(session->destination(),transfer->name(),session->source()); qDebug() << Q_FUNC_INFO << __LINE__; connect(receiving_widget,&FileReceivingPopupWidget::accepted,this,[=]{ request.accept(transfer->name()); receiving_widget->configuration_transfer_progress_bar(transfer->size()); connect(transfer.data(),&BluezQt::ObexTransfer::transferredChanged,receiving_widget,&FileReceivingPopupWidget::update_transfer_progress_bar); connect(transfer.data(),&BluezQt::ObexTransfer::statusChanged,receiving_widget,&FileReceivingPopupWidget::file_transfer_completed); connect(receiving_widget,&FileReceivingPopupWidget::cancel,this,[=]{ transfer->cancel(); qDebug() << Q_FUNC_INFO << "cancel" << __LINE__; //receiveDisConnectSignal(session->destination()); }); }); connect(receiving_widget,&FileReceivingPopupWidget::rejected,this,[=]{ request.reject(); }); receiving_widget->show(); } // qDebug() << Q_FUNC_INFO << transfer->status() << transfer->type() << transfer->fileName() << transfer->transferred(); } QDBusObjectPath BluetoothObexAgent::objectPath() const { qDebug() << Q_FUNC_INFO; return QDBusObjectPath(QStringLiteral("/org/bluez/obex/Agent1")); } void BluetoothObexAgent::cancel() { qDebug() << Q_FUNC_INFO; if (nullptr == receiving_widget) { qDebug() << Q_FUNC_INFO << "receiving_widget is null" ; return ; } receiving_widget->file_transfer_completed(BluezQt::ObexTransfer::Error); } void BluetoothObexAgent::release() { qDebug() << Q_FUNC_INFO; } int BluetoothObexAgent::daemonIsNotRunning() { QDBusConnection conn = QDBusConnection::sessionBus(); if (!conn.isConnected()) return 0; QDBusReply reply = conn.interface()->call("GetNameOwner", "org.bluez.obex.Agent1"); return reply.value() == ""; } void BluetoothObexAgent::receiveDisConnectSignal(QString address) { qDebug() << Q_FUNC_INFO << address << __LINE__; QDBusMessage m = QDBusMessage::createMethodCall("org.ukui.bluetooth","/org/ukui/bluetooth","org.ukui.bluetooth","disConnectToDevice"); m << address; qDebug() << Q_FUNC_INFO << m.arguments().at(0).value() <<__LINE__; // 发送Message QDBusMessage response = QDBusConnection::sessionBus().call(m); } ukui-bluetooth/ukui-bluetooth/agent/bluetoothobexagent.h0000644000175000017500000000416714201620261022611 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2021 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 BLUETOOTHOBEXAGENT_H #define BLUETOOTHOBEXAGENT_H #include "fileReceive/filereceivingpopupwidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class FileReceivingPopupWidget; class BluetoothObexAgent : public BluezQt::ObexAgent { Q_OBJECT public: explicit BluetoothObexAgent(QObject *parent = nullptr); void authorizePush (BluezQt::ObexTransferPtr transfer,BluezQt::ObexSessionPtr session, const BluezQt::Request &request); QDBusObjectPath objectPath() const override; void cancel (); void release (); int daemonIsNotRunning(); void receiveDisConnectSignal(QString address); private: FileReceivingPopupWidget *receiving_widget ; }; #endif // BLUETOOTHOBEXAGENT_H ukui-bluetooth/ukui-bluetooth/agent/bluetoothagent.cpp0000644000175000017500000001727614201620261022273 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2021 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 "bluetoothagent.h" BluetoothAgent::BluetoothAgent(QObject *parent) : Agent(parent) , m_pinRequested(false) , m_passkeyRequested(false) , m_authorizationRequested(false) , m_cancelCalled(false) , m_releaseCalled(false) , m_hasClosePinCode(false) { qDebug() << Q_FUNC_INFO; if(daemonIsNotRunning()){ QDBusConnection bus = QDBusConnection::systemBus(); // 在session bus上注册名为"org.bluez.Agent1"的service if (!bus.registerService("org.bluez.Agent1")) { //注意命名规则-和_ qDebug() << bus.lastError().message(); exit(1); } // "QDBusConnection::ExportAllSlots"表示把类Hotel的所有Slot都导出为这个Object的method bus.registerObject("/", this ,QDBusConnection::ExportAllContents); } } void BluetoothAgent::emitRemoveSignal(BluezQt::DevicePtr device) { if (device.data()->isPaired()) { QTimer::singleShot(100,this,[=]{ emit agentRemoveDevice(device); }); } } QDBusObjectPath BluetoothAgent::objectPath() const { return QDBusObjectPath(QStringLiteral("/BluetoothAgent")); } void BluetoothAgent::requestPinCode(BluezQt::DevicePtr device, const BluezQt::Request &request) { qDebug() << Q_FUNC_INFO; m_device = device; m_pinRequested = true; m_hasClosePinCode = true; emit stopNotifyTimer(device); Keypincodewidget = new PinCodeWidget(device->name(), true); connect(Keypincodewidget,&PinCodeWidget::accepted,this,[=]{ request.accept(Keypincodewidget->getEnteredPINCode()); emit startNotifyTimer(device); m_hasClosePinCode = false; return; }); connect(Keypincodewidget,&PinCodeWidget::rejected,this,[=]{ request.reject(); m_hasClosePinCode = false; return; }); connect(device.data(), &BluezQt::Device::pairedChanged, this, [=](bool st){ if (st == false) { request.reject(); if (pincodewidget != nullptr && m_hasClosePinCode != false) { m_hasClosePinCode = false; pincodewidget->close(); } } return; }); connect(Keypincodewidget, &PinCodeWidget::destroyed, this, [=] { Keypincodewidget = nullptr; m_hasClosePinCode = false; }); //保持在最前 Keypincodewidget->show(); Keypincodewidget->activateWindow(); } void BluetoothAgent::displayPinCode(BluezQt::DevicePtr device, const QString &pinCode) { m_device = device; m_displayedPinCode = pinCode; printf("\n\nCCCCCCCCCCCCCCCCCC - %s\n\n", pinCode.toStdString().data()); qDebug() << Q_FUNC_INFO; } void BluetoothAgent::requestPasskey(BluezQt::DevicePtr device, const BluezQt::Request &request) { qDebug() << Q_FUNC_INFO; m_device = device; m_passkeyRequested = true; request.accept(0); } void BluetoothAgent::displayPasskey(BluezQt::DevicePtr device, const QString &passkey, const QString &entered) { qDebug() << Q_FUNC_INFO << ( m_device.isNull() ? "NULL" : m_device.data()->address() ) << entered << passkey; if(m_displayedPasskey == passkey) return; emit stopNotifyTimer(device); m_device = device; m_displayedPasskey = passkey; m_enteredPasskey = entered; connect(device.data(), &BluezQt::Device::pairedChanged, this, [=](bool st){ qDebug() << Q_FUNC_INFO << st << __LINE__; if (st) { if (Keypincodewidget) { Keypincodewidget->setHidden(true); emit startNotifyTimer(device); } }else{ if(Keypincodewidget){} // Keypincodewidget->close(); QTimer::singleShot(1000,this,[=]{ qDebug() << Q_FUNC_INFO << device.data()->isConnected() << __LINE__; if (!device.data()->isConnected()) Keypincodewidget->pairFailureShow(); }); disconnect(device.data(), &BluezQt::Device::pairedChanged, nullptr, nullptr); } }); if(Keypincodewidget != nullptr){ if (Keypincodewidget) { Keypincodewidget->updateUIInfo(device.data()->name(),passkey); return; } } Keypincodewidget = new PinCodeWidget(device->name(),passkey,false); //保持在最前 Keypincodewidget->show(); Keypincodewidget->activateWindow(); } void BluetoothAgent::requestConfirmation(BluezQt::DevicePtr device, const QString &passkey, const BluezQt::Request<> &request) { qDebug() << Q_FUNC_INFO << device->name() << passkey; if(pincodewidget != nullptr){ return; } emit stopNotifyTimer(device); m_device = device; m_requestedPasskey = passkey; pincodewidget = new PinCodeWidget(device->name(),passkey); m_hasClosePinCode = true; connect(pincodewidget,&PinCodeWidget::accepted,this,[=]{ request.accept(); emit startNotifyTimer(device); return; }); connect(pincodewidget,&PinCodeWidget::rejected,this,[=]{ request.reject(); emitRemoveSignal(device); return; }); connect(m_device.data(), &BluezQt::Device::pairedChanged, this, [=](bool st){ if (st == false) { request.reject(); if (pincodewidget != nullptr && m_hasClosePinCode != false) { m_hasClosePinCode = false; pincodewidget->close(); emitRemoveSignal(device); } } return; }); connect(pincodewidget, &PinCodeWidget::destroyed, this, [=] { pincodewidget = nullptr; m_cancelCalled = false; }); //保持在最前 pincodewidget->show(); pincodewidget->activateWindow(); // request.accept(); } void BluetoothAgent::requestAuthorization(BluezQt::DevicePtr device, const BluezQt::Request<> &request) { qDebug() << Q_FUNC_INFO << device->name(); m_device = device; m_authorizationRequested = true; request.accept(); } void BluetoothAgent::authorizeService(BluezQt::DevicePtr device, const QString &uuid, const BluezQt::Request<> &request) { qDebug() << Q_FUNC_INFO << device->name(); m_device = device; m_authorizedUuid = uuid; request.accept(); } void BluetoothAgent::cancel() { qDebug() << Q_FUNC_INFO; if (m_cancelCalled) return; if (pincodewidget != nullptr && m_hasClosePinCode != false) { m_cancelCalled = true; m_hasClosePinCode = false; pincodewidget->Connection_timed_out(); emitRemoveSignal(m_device); } } void BluetoothAgent::release() { qDebug() << Q_FUNC_INFO; m_releaseCalled = true; } int BluetoothAgent::daemonIsNotRunning() { QDBusConnection conn = QDBusConnection::systemBus(); if (!conn.isConnected()) return 0; QDBusReply reply = conn.interface()->call("GetNameOwner", "org.bluez.Agent1"); return reply.value() == ""; } ukui-bluetooth/ukui-bluetooth/agent/bluetoothagent.h0000644000175000017500000000652114201620261021727 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2021 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 BLUETOOTHAGENT_H #define BLUETOOTHAGENT_H #include "pin/pincodewidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include class PinCodeWidget; class BluetoothAgent : public BluezQt::Agent { Q_OBJECT public: explicit BluetoothAgent(QObject *parent = nullptr); QDBusObjectPath objectPath() const override; void requestPinCode(BluezQt::DevicePtr device, const BluezQt::Request &request) override; void displayPinCode(BluezQt::DevicePtr device, const QString &pinCode) override; void requestPasskey(BluezQt::DevicePtr device, const BluezQt::Request &request) override; void displayPasskey(BluezQt::DevicePtr device, const QString &passkey, const QString &entered) override; void requestConfirmation(BluezQt::DevicePtr device, const QString &passkey, const BluezQt::Request<> &request) override; void requestAuthorization(BluezQt::DevicePtr device, const BluezQt::Request<> &request) override; void authorizeService(BluezQt::DevicePtr device, const QString &uuid, const BluezQt::Request<> &request) override; void cancel() override; void release() override; int daemonIsNotRunning(); void emitRemoveSignal(BluezQt::DevicePtr device); signals: void requestAccept(); void requestReject(); void stopNotifyTimer(BluezQt::DevicePtr); void startNotifyTimer(BluezQt::DevicePtr); void agentRemoveDevice(BluezQt::DevicePtr); private: int64_t _pinCodeDisplay; BluezQt::DevicePtr m_device; // requestPinCode bool m_pinRequested; // displayPinCode QString m_displayedPinCode; // requestPasskey bool m_passkeyRequested; // displayPasskey QString m_displayedPasskey; QString m_enteredPasskey; // requestConfirmation QString m_requestedPasskey; // requestAuthorization bool m_authorizationRequested; // authorizeService QString m_authorizedUuid; // cancel bool m_cancelCalled; // release bool m_releaseCalled; bool m_hasClosePinCode; PinCodeWidget *pincodewidget = nullptr; PinCodeWidget *Keypincodewidget = nullptr; }; #endif // BLUETOOTHAGENT_H ukui-bluetooth/service/0000755000175000017500000000000014205120337014113 5ustar fengfengukui-bluetooth/service/service.pro0000644000175000017500000000303514201160062016271 0ustar fengfeng###################################################################### # Automatically generated by qmake (3.1) Thu Mar 4 18:08:23 2021 ###################################################################### TEMPLATE = app TARGET = bluetoothService INCLUDEPATH += . QT += core dbus QT -= gui CONFIG += c++11 link_pkgconfig PKGCONFIG += gio-2.0 LIBS += -lglib-2.0 QMAKE_LFLAGS += -D_FORTIFY_SOURCE=2 -O2 ins1.files += ../data/com.bluetooth.systemdbus.conf ins1.path = /etc/dbus-1/system.d/ ins2.files += ../data/com.bluetooth.systemdbus.service ins2.path = /usr/share/dbus-1/system-services/ ins3.files += ../data/com.bluetooth.systemdbus.policy ins3.path = /usr/share/polkit-1/actions/ target.source += $$TARGET target.path = /usr/bin/ INSTALLS += ins1 \ ins2 \ ins3 \ target # The following define makes your compiler warn you 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 # 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 # Input #HEADERS += SOURCES += main.cpp \ sysdbusregister.cpp HEADERS += \ sysdbusregister.h ukui-bluetooth/service/sysdbusregister.h0000644000175000017500000000311014201620261017515 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2021 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 SYSDBUSREGISTER_H #define SYSDBUSREGISTER_H #include #include #include #include #include #include #include #include #include #define LIST_PATH "/etc/pairDevice.list" class SysDbusRegister : public QObject, protected QDBusContext { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "com.bluetooth.interface") public: SysDbusRegister(); ~SysDbusRegister(); private: public slots: Q_SCRIPTABLE int exitService(); Q_SCRIPTABLE QString writeKeyFile(QString,QString,qint32); Q_SCRIPTABLE QString removeKeyFile(QString); Q_SCRIPTABLE QString getKeyFilePath(); }; #endif // SYSDBUSREGISTER_H ukui-bluetooth/service/sysdbusregister.cpp0000644000175000017500000000723014201620261020057 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2021 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 "sysdbusregister.h" SysDbusRegister::SysDbusRegister() { } SysDbusRegister::~SysDbusRegister() { } int SysDbusRegister::exitService() { qApp->exit(0); return 0; } QString SysDbusRegister::writeKeyFile(QString devAddress, QString devName, qint32 type) { if(devAddress.isNull()) return QString("Address can not be empty ! ! !"); if(devName.isNull()) return QString("Name can not be empty ! ! !"); if(devAddress.at(2) != ":" || devAddress.at(5) != ":" || devAddress.at(8) != ":" || devAddress.at(11) != ":" || devAddress.at(14) != ":") return QString("arg0 is not an address ! ! !"); if(!QFile::exists(LIST_PATH)){ QFile file(LIST_PATH); file.open(QIODevice::WriteOnly); file.close(); } GKeyFile *key_file = nullptr; key_file = g_key_file_new(); char *data; gsize length = 0; g_key_file_load_from_file(key_file,QString(LIST_PATH).toStdString().c_str(),G_KEY_FILE_NONE,NULL); g_key_file_set_string(key_file,devAddress.toStdString().c_str(),"Name",devName.toStdString().c_str()); g_key_file_set_string(key_file,devAddress.toStdString().c_str(),"Type",QString("%1").arg(type).toStdString().c_str()); g_key_file_set_string(key_file,devAddress.toStdString().c_str(),"ConnectTime",QString::number(QDateTime::currentMSecsSinceEpoch() / 1000).toStdString().c_str()); data = g_key_file_to_data(key_file,&length,NULL); g_file_set_contents(QString(LIST_PATH).toStdString().c_str(),data,length,NULL); g_free(data); g_key_file_free(key_file); return QString("Key write ok!!!"); } QString SysDbusRegister::removeKeyFile(QString devAddress) { if(devAddress.isNull()) return QString("Address can not be empty ! ! !"); if(devAddress.at(2) != ":" || devAddress.at(5) != ":" || devAddress.at(8) != ":" || devAddress.at(11) != ":" || devAddress.at(14) != ":") return QString("arg0 is not an address ! ! !"); if(!QFile::exists(LIST_PATH)){ QFile file(LIST_PATH); file.open(QIODevice::WriteOnly); file.close(); } GKeyFile *key_file = nullptr; char *data; gsize length = 0; GError *error; key_file = g_key_file_new(); g_key_file_load_from_file(key_file,QString(LIST_PATH).toStdString().c_str(),G_KEY_FILE_NONE,NULL); if(g_key_file_has_group(key_file,devAddress.toStdString().c_str())){ g_key_file_remove_group(key_file,devAddress.toStdString().c_str(),&error); data = g_key_file_to_data(key_file,&length,NULL); g_file_set_contents(QString(LIST_PATH).toStdString().c_str(),data,length,NULL); g_free(data); } g_key_file_free(key_file); return QString("Key remove ok!!!"); } QString SysDbusRegister::getKeyFilePath() { return QString(LIST_PATH); } ukui-bluetooth/service/main.cpp0000644000175000017500000000321014201620261015534 0ustar fengfeng/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2021 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 #include #include #include "sysdbusregister.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); a.setOrganizationName("Kylin Team"); a.setApplicationName("system-bus-bluetooth-service"); QDBusConnection systemBus = QDBusConnection::systemBus(); if (!systemBus.registerService("com.bluetooth.systemdbus")){ qCritical() << "QDbus register service failed reason:" << systemBus.lastError(); //exit(1); } if (!systemBus.registerObject("/", "com.bluetooth.interface", new SysDbusRegister(), QDBusConnection::ExportAllSlots)){ qCritical() << "QDbus register object failed reason:" << systemBus.lastError(); //exit(2); } // qDebug() << "ok"; return a.exec(); } ukui-bluetooth/README.md0000644000175000017500000000010714201160062013723 0ustar fengfeng# UKUI-Bluetooth ## Simple bluetooth tool for ukui desktop environment ukui-bluetooth/.gitattributes0000644000175000017500000000012514201160062015337 0ustar fengfengdebian/changelog merge=ours debian/compat merge=ours debian/source/format merge=ours